内核技术:TCP/IP编程实现远程文件传输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选项。 现在,我们可以针对文章开头提出的问题着手进行编程了。在图示的网络结构中,为使中心机房的服务器能和网点上的客户机进行通信,需在服务器端添加通过路由器1112到客户机的路由,两台客户机也必须添加通过路由器2221到服务器的路由。在服务器的/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 #include #include #include #include #include #include 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)); /*发送文件名*/
更多相关文章
|
推荐文章
精彩文章
|