我想问一下,在C++中如何用TCP实现文件传输,
比如说,我要传送XML文件,如果我用SOAP协议。该怎么办呢?我只学习过理论,具体到如何使用这些协议,我就是一小白。是不是VC6.0把这些协议的API都封装好了啊??请大...
比如说,我要传送 XML文件,如果我用SOAP协议。 该怎么办呢?
我只学习过理论,具体到 如何使用这些协议,我就是一小白。是不是VC 6.0把这些协议的API都封装好了啊??
请大家给点切实可行的建议。
我要的不是 socket,TCP和UDP我想对还熟悉。
我的疑问是,比如说,使用广播地址发送广播,来看下 前端设备是否具有反馈数据,这样才能得知设备是否已经启动!
请问这个 广播地址我在代码里面如何实现啊? 展开
我只学习过理论,具体到 如何使用这些协议,我就是一小白。是不是VC 6.0把这些协议的API都封装好了啊??
请大家给点切实可行的建议。
我要的不是 socket,TCP和UDP我想对还熟悉。
我的疑问是,比如说,使用广播地址发送广播,来看下 前端设备是否具有反馈数据,这样才能得知设备是否已经启动!
请问这个 广播地址我在代码里面如何实现啊? 展开
1个回答
展开全部
SOAP,是一种用于在非集中、分布式环境中交换信息的轻型网络协议。它是一种基于 XML 的协议,由三部分组成:
1.一个定义框架的封套,用于描述消息的内容以及如何对它进行处理
2.一组表示应用程序定义的数据类型实例的编码规则
3.一个表示远程过程调用和响应的约定
iAMT编程接口是iAMT FirmWare提供的基于 SOAP 的 API,可与远程主机上运行的 ISV 管理控制台软件进行通信。在 Web 服务描述语言(WSDL)中对 API 进行了描述。每个固件服务(也称为接口)都有一个 WSDL 文件。
1.Socket系统调用
为了进行网络I/O,服务器和客户机两端的UNIX进程要做的第一件事是调用socket()系统调用,建立软插座,指明合适的通讯协议。格式为:
#include<sys/types.h>
#include<sys/socket.h>
int socket(int family,int type,int protocol)
其中:(1)family指明套节字族,其值包括:
AF_UNIX (UNIX内部协议族)
AF_INET (Iternet协议)
AF_NS (XeroxNs协议,TCP/IP编程取该值)
AF_IMPLINK (IMP链接层)
(2)type 指明套接字类型,取值有:
SOCK_STREAM (流套接字)
SOCK_DGRAM (数据报套接字)
SOCK_RAW (原始套接字)
SOCK_SEQPACKET (定序分组套接字)
2.服务器端Bind系统调用
软插座创建时并没有和所有地址相关联,必须用bind()系统调用为其建立地址联系。其格式为:
#include<sys/types.h>
#include<sys/socket.h>
int bind(int socketfd,struct sockaddr_in *localaddr,sizeof(localaddr));
其中:(1)第一个参数socketfd是前步socket()系统调用返回的套节字描述符。
(2)第二个参数被捆向本地地址的一种结构,该结构在sys/netinet/in.h中定义:
struct sockaddr_in{
short sin_family;/*socket()系统调用的协议族如AF_INET*/
u_short sin_port;/*网络字节次序形式的端口号码*/
struct in_addr sin_addr;/*网络字节次序形式的网络地址*/
char sin_zero[8];
}
(3)第三个参数为第二个结构参数的长度,如果调用成功,bind返回0,否则将返回-1并设置errno。
3.服务器端系统调用listen,使服务器愿意接受连接
格式:int listen(int socketfd,int backlong)
他通常在socket和bind调用后在accept调用前执行。第二个参数指明在等待服务器执行accept调用时系统能排队多少个连接需求。此参数常指定为5,也是目前允许的最大值。
4.服务器调用accept,以等待客户机调用connect进行连接。格式如下:
int newsocket=(int socketfd,struct sockaddr_in *peer,int*addrlen);
该调用取得队列上的第一个连接请求并建立一个具有和sockfd相同特性的套节字。如果没有等待的连接请求,此调用阻塞调用者直到一连接请求到达。连接成功后,该调用将用对端的地址结构和地址长度填充参数peer和addlen,如果对客户端的地址信息不感兴趣,这两个参数用0代替。
5.客户端调用connect()和服务器建立连接。格式为:
connect(int socketfd,struct sockaddr_in *servsddr,int addrlen)
客户端取得套接字描述符后,用该调用建立和服务器的连接,参数socketfd为socket()系统调用返回的套节字描述符,第二和第三个参数是指向目的地址的结构及以字节计量的目的地址的长度(这里目的地址应为服务器地址)。调用成功返回0,否则将返回-1并设置errno。
6.通过软插座发送数据
一旦建立连接,就能用系统调用read和write像普通文件那样向网络上发送和接受数据。Read接受三个参数:一个是套节字描述符;一个为数据将被填入的缓冲区,更有一个整数指明要读的字节数,他返回实际读入的字节数,出错时返回-1,遇见文件尾则返回0。Write也接受三个参数:一个是套节字描述符;一个为指向需要发送数据的缓冲区,更有一个整数指明要写入文件的字节个数,他返回实际写入的字节数,出错时返回-1。当然,也能调用send和recv来对套节字进行读写,其调用和基本的read和write系统调用相似,只是多了一个发送方式参数。
7.退出程式时,应按正常方式关闭套节字。格式如下:
int close(socketfd)
前面介绍了UNIX客户/服务器模式网络编程的基本思路和步骤。值得指出的是socket编程所涉及的系统调用不属于基本系统调用范围,其函数原形在libsocket.a文件中,因此,在用cc命令对原程式进行编译时需要带-lsocket选项。
目前,我们能针对文章开头提出的问题着手进行编程了。在图示的网络结构中,为使中心机房的服务器能和网点上的客户机进行通信,需在服务器端添加通过路由器1?1?1?2到客户机的路由,两台客户机也必须添加通过路由器2?2?2?1到服务器的路由。在服务器的/etc/hosts文件中应该包含下面内容:
1.1.1.1 server
2.2.2.2 cli1
2.2.2.3 cli2
客户机的/etc/hosts文件中应该有本机地址信息和服务器的地址信息,如cli1客户机的/etc/hosts文件:
2.2.2.2 cli1
1.1.1.1 server
网络环境搭建好后,我们能在服务器端编写fwq.c程式,负责接受客户机的连接请求,并将从源文件中读取的数据发送到客户机。客户机程式khj.c向服务器发送连接请求,接收从服务器端发来的数据,并将接收到的数据写入目标文件。源程式如下:
/*服务器源程式fwq.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<sys/socket.h>
#include<sys/netinet/in.h>
#include<netdb.h>
#include<errno.h>
main()
{
char c,buf[1024],file[30];
int fromlen,source;
register int k,s,ns;
struct sockaddr_in sin;
struct hostent *hp;
system(〃clear〃);
printf(〃\n〃);
printf(〃\n\n\t\t输入要传输的文件名:〃);
scanf(〃%s〃,file);
if ((source=open(file,O_RDONLY))<0){
perror(〃源文件打开出错〃);
exit(1);
}
printf(〃\n\t\t在传送文件,稍候…〃);
hp=gethostbyname(〃server〃);
if (hp==NULL){
perror(〃返回主机地址信息错!!!〃);
exit(2);
}
s=socket(AF_INET,SOCK_STREAM,0);
if(s<0){
perror(〃获取SOCKET号失败!!!〃);
exit(3);
}
sin.sin_family=AF_INET;
sin.sin_port=htons(1500);/*使用端口1500*/
bcopy(hp->h_addr,&sin.sin_addr,hp->h_length);
if(bind(s,&sin,sizeof(sin))<0){
perror(〃不能将服务器地址捆绑到SOCKET号上!!!〃);
colse(s);
exit(4);
}
if(listen(s,5)<0{
perror(〃sever:listen〃);
exit(5);
}
while(1){
if((ns=accept(s,&sin,&fromlen))<0){
perror(〃sever:accept〃);
exit(6);
}
lseek(source,OL,0);/*每次接受客户机连接,应将用于读的源文件指针移到文件头*/
write(ns,file,sizeof(file)); /*发送文件名*/
while((k=read(source,buf,sizeof(buf)))>0)
write(ns,buf,k);
printf(〃\n\n\t\t传输完毕!!!\n〃);
close(ns);
}
close(source);
exit(0);
/*客户机源程式khj.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<sys/socket.h>
#include<sys/netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include <string.h>
main()
{
char buf[1024],file[30];
char *strs=〃\n\n\t\t正在接收文件〃;
int target;
register int k,s;
struct sockaddr_in sin;
struct hostent *hp;
system(〃clear〃);
printf(〃\n〃);
hp=gethostbyname(〃server〃);
if(hp==NULL){
perror(〃返回服务器地址信息错!!!〃);
exit(1);
}
s=socket(AF_INET,SOCK_STREAM,0);
if(s<0){
perror(〃获取SOCKET号失败!!!〃);
exit(2);
}
sin.sin_family=AF_INET;
sin.sin_port=htons(1500);/*端口号需和服务器程式使用的一致*/
bcopy(hp->h_addr,&sin.sin_addr,hp->h_length);
printf(〃\n\n\t\t正在和服务器连接…〃);
if(connect(s,&sin,sizeof(sin),0)<0){
perror(〃不能和服务器连接!!!〃);
exit(3);
}
while((k=read(s,file,sizeof(file)))<=0/*接收文件名*/
if((target=open(file,o_WRONLY|O_CREAT|O_TRUNC,0644))<0){
perror(〃不能打开目标文件!!〃);
exit(4);
}
strcat(strs,file);
strcat(strs,〃,稍候…〃);
write(1,strs,strlen(strs));
while((k=read(s,buf,sizeof(buf)))>0)
write(tatget,buf,k);
printf(〃\n\n\t\t接收文件成功!!!\n〃);
close(s);
close(target);
}
上述程式在Sco Unix System v3.2及Sco TCP/IP Rumtime环境下调试通过。
1.一个定义框架的封套,用于描述消息的内容以及如何对它进行处理
2.一组表示应用程序定义的数据类型实例的编码规则
3.一个表示远程过程调用和响应的约定
iAMT编程接口是iAMT FirmWare提供的基于 SOAP 的 API,可与远程主机上运行的 ISV 管理控制台软件进行通信。在 Web 服务描述语言(WSDL)中对 API 进行了描述。每个固件服务(也称为接口)都有一个 WSDL 文件。
1.Socket系统调用
为了进行网络I/O,服务器和客户机两端的UNIX进程要做的第一件事是调用socket()系统调用,建立软插座,指明合适的通讯协议。格式为:
#include<sys/types.h>
#include<sys/socket.h>
int socket(int family,int type,int protocol)
其中:(1)family指明套节字族,其值包括:
AF_UNIX (UNIX内部协议族)
AF_INET (Iternet协议)
AF_NS (XeroxNs协议,TCP/IP编程取该值)
AF_IMPLINK (IMP链接层)
(2)type 指明套接字类型,取值有:
SOCK_STREAM (流套接字)
SOCK_DGRAM (数据报套接字)
SOCK_RAW (原始套接字)
SOCK_SEQPACKET (定序分组套接字)
2.服务器端Bind系统调用
软插座创建时并没有和所有地址相关联,必须用bind()系统调用为其建立地址联系。其格式为:
#include<sys/types.h>
#include<sys/socket.h>
int bind(int socketfd,struct sockaddr_in *localaddr,sizeof(localaddr));
其中:(1)第一个参数socketfd是前步socket()系统调用返回的套节字描述符。
(2)第二个参数被捆向本地地址的一种结构,该结构在sys/netinet/in.h中定义:
struct sockaddr_in{
short sin_family;/*socket()系统调用的协议族如AF_INET*/
u_short sin_port;/*网络字节次序形式的端口号码*/
struct in_addr sin_addr;/*网络字节次序形式的网络地址*/
char sin_zero[8];
}
(3)第三个参数为第二个结构参数的长度,如果调用成功,bind返回0,否则将返回-1并设置errno。
3.服务器端系统调用listen,使服务器愿意接受连接
格式:int listen(int socketfd,int backlong)
他通常在socket和bind调用后在accept调用前执行。第二个参数指明在等待服务器执行accept调用时系统能排队多少个连接需求。此参数常指定为5,也是目前允许的最大值。
4.服务器调用accept,以等待客户机调用connect进行连接。格式如下:
int newsocket=(int socketfd,struct sockaddr_in *peer,int*addrlen);
该调用取得队列上的第一个连接请求并建立一个具有和sockfd相同特性的套节字。如果没有等待的连接请求,此调用阻塞调用者直到一连接请求到达。连接成功后,该调用将用对端的地址结构和地址长度填充参数peer和addlen,如果对客户端的地址信息不感兴趣,这两个参数用0代替。
5.客户端调用connect()和服务器建立连接。格式为:
connect(int socketfd,struct sockaddr_in *servsddr,int addrlen)
客户端取得套接字描述符后,用该调用建立和服务器的连接,参数socketfd为socket()系统调用返回的套节字描述符,第二和第三个参数是指向目的地址的结构及以字节计量的目的地址的长度(这里目的地址应为服务器地址)。调用成功返回0,否则将返回-1并设置errno。
6.通过软插座发送数据
一旦建立连接,就能用系统调用read和write像普通文件那样向网络上发送和接受数据。Read接受三个参数:一个是套节字描述符;一个为数据将被填入的缓冲区,更有一个整数指明要读的字节数,他返回实际读入的字节数,出错时返回-1,遇见文件尾则返回0。Write也接受三个参数:一个是套节字描述符;一个为指向需要发送数据的缓冲区,更有一个整数指明要写入文件的字节个数,他返回实际写入的字节数,出错时返回-1。当然,也能调用send和recv来对套节字进行读写,其调用和基本的read和write系统调用相似,只是多了一个发送方式参数。
7.退出程式时,应按正常方式关闭套节字。格式如下:
int close(socketfd)
前面介绍了UNIX客户/服务器模式网络编程的基本思路和步骤。值得指出的是socket编程所涉及的系统调用不属于基本系统调用范围,其函数原形在libsocket.a文件中,因此,在用cc命令对原程式进行编译时需要带-lsocket选项。
目前,我们能针对文章开头提出的问题着手进行编程了。在图示的网络结构中,为使中心机房的服务器能和网点上的客户机进行通信,需在服务器端添加通过路由器1?1?1?2到客户机的路由,两台客户机也必须添加通过路由器2?2?2?1到服务器的路由。在服务器的/etc/hosts文件中应该包含下面内容:
1.1.1.1 server
2.2.2.2 cli1
2.2.2.3 cli2
客户机的/etc/hosts文件中应该有本机地址信息和服务器的地址信息,如cli1客户机的/etc/hosts文件:
2.2.2.2 cli1
1.1.1.1 server
网络环境搭建好后,我们能在服务器端编写fwq.c程式,负责接受客户机的连接请求,并将从源文件中读取的数据发送到客户机。客户机程式khj.c向服务器发送连接请求,接收从服务器端发来的数据,并将接收到的数据写入目标文件。源程式如下:
/*服务器源程式fwq.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<sys/socket.h>
#include<sys/netinet/in.h>
#include<netdb.h>
#include<errno.h>
main()
{
char c,buf[1024],file[30];
int fromlen,source;
register int k,s,ns;
struct sockaddr_in sin;
struct hostent *hp;
system(〃clear〃);
printf(〃\n〃);
printf(〃\n\n\t\t输入要传输的文件名:〃);
scanf(〃%s〃,file);
if ((source=open(file,O_RDONLY))<0){
perror(〃源文件打开出错〃);
exit(1);
}
printf(〃\n\t\t在传送文件,稍候…〃);
hp=gethostbyname(〃server〃);
if (hp==NULL){
perror(〃返回主机地址信息错!!!〃);
exit(2);
}
s=socket(AF_INET,SOCK_STREAM,0);
if(s<0){
perror(〃获取SOCKET号失败!!!〃);
exit(3);
}
sin.sin_family=AF_INET;
sin.sin_port=htons(1500);/*使用端口1500*/
bcopy(hp->h_addr,&sin.sin_addr,hp->h_length);
if(bind(s,&sin,sizeof(sin))<0){
perror(〃不能将服务器地址捆绑到SOCKET号上!!!〃);
colse(s);
exit(4);
}
if(listen(s,5)<0{
perror(〃sever:listen〃);
exit(5);
}
while(1){
if((ns=accept(s,&sin,&fromlen))<0){
perror(〃sever:accept〃);
exit(6);
}
lseek(source,OL,0);/*每次接受客户机连接,应将用于读的源文件指针移到文件头*/
write(ns,file,sizeof(file)); /*发送文件名*/
while((k=read(source,buf,sizeof(buf)))>0)
write(ns,buf,k);
printf(〃\n\n\t\t传输完毕!!!\n〃);
close(ns);
}
close(source);
exit(0);
/*客户机源程式khj.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<sys/socket.h>
#include<sys/netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include <string.h>
main()
{
char buf[1024],file[30];
char *strs=〃\n\n\t\t正在接收文件〃;
int target;
register int k,s;
struct sockaddr_in sin;
struct hostent *hp;
system(〃clear〃);
printf(〃\n〃);
hp=gethostbyname(〃server〃);
if(hp==NULL){
perror(〃返回服务器地址信息错!!!〃);
exit(1);
}
s=socket(AF_INET,SOCK_STREAM,0);
if(s<0){
perror(〃获取SOCKET号失败!!!〃);
exit(2);
}
sin.sin_family=AF_INET;
sin.sin_port=htons(1500);/*端口号需和服务器程式使用的一致*/
bcopy(hp->h_addr,&sin.sin_addr,hp->h_length);
printf(〃\n\n\t\t正在和服务器连接…〃);
if(connect(s,&sin,sizeof(sin),0)<0){
perror(〃不能和服务器连接!!!〃);
exit(3);
}
while((k=read(s,file,sizeof(file)))<=0/*接收文件名*/
if((target=open(file,o_WRONLY|O_CREAT|O_TRUNC,0644))<0){
perror(〃不能打开目标文件!!〃);
exit(4);
}
strcat(strs,file);
strcat(strs,〃,稍候…〃);
write(1,strs,strlen(strs));
while((k=read(s,buf,sizeof(buf)))>0)
write(tatget,buf,k);
printf(〃\n\n\t\t接收文件成功!!!\n〃);
close(s);
close(target);
}
上述程式在Sco Unix System v3.2及Sco TCP/IP Rumtime环境下调试通过。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询