《UNIX网络编程》中第一个timer_server的例子

 1.配置环境

    在这里下载unpv13e.tar.gz,其中包含了《UNIX网络编程》第一卷的源代码。假设将其移到~/Unix/Network/目录下,以下为配置过程(假设当前目录为下载目录):


  1. mv ./unpv13e.tar.gz ~/Unix/Network 
  2.  
  3.     cd ~/Unix/Network
  4.  
  5.     tar -zxvf unpv13e.tar.gz 
  6.  
  7.     cd unpv13e
  8.  
  9.     ./configure 
  10.  
  11.     cd lib 
  12.  
  13.     make 
  14.  
  15.     cd ../                  #back to unpv13e/ 
  16.  
  17.     cp libunp.a /usr/lib 
  18.  
  19.     cp libunp.a /usr/lib64
  20.  
  21.     cd ../                  #back to Network/ 
  22.  
  23.     cp ./unpv13e/lib/unp.h ./ 
  24.  
  25.     cp ./unpv13e/config.h ./ 
  26.  
  27.     vi unp.h #使用vi将unp.h中的 #include "../config.h"改为#include "./config.h" 
  28.  
  29.     mkdir timer_server 
  30.  
  31.     cd timer_server 

2.编写代码    

 编写服务端代码:


  1. #include "../unp.h" 
  2.  
  3. int main(int argc,char *argv[]) 
  4.     int listenfd,connfd; 
  5.     struct sockaddr_in servaddr; 
  6.     char buff[MAXLINE]; 
  7.     time_t ticks; 
  8.     listenfd = Socket(AF_INET,SOCK_STREAM,0); 
  9.     bzero(&servaddr,sizeof(servaddr)); 
  10.     servaddr.sin_family = AF_INET; 
  11.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  12.     servaddr.sin_port=htons(13); 
  13.     Bind(listenfd,(SA*)&servaddr,sizeof(servaddr)); 
  14.     Listen(listenfd,LISTENQ); 
  15.     for(;;) 
  16.     { 
  17.         connfd = Accept(listenfd,(SA*)NULL,NULL); 
  18.         ticks = time(NULL); 
  19.         snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks)); 
  20.         Write(connfd,buff,strlen(buff)); 
  21.         Close(connfd); 
  22.     } 
  23.     return 0; 

      编写客户端代码:


  1. #include "../unp.h" 
  2.  
  3. int main(int argc,char *argv[]) 
  4.     int socketfd,n; 
  5.     char recvline[MAXLINE+1]; 
  6.     struct sockaddr_in servaddr; 
  7.     if(argc != 2) 
  8.         err_quit("Usage:%s <IP Address>",argv[0]); 
  9.     if( (socketfd = socket(AF_INET,SOCK_STREAM,0)) <0 ) 
  10.         err_sys("socket error"); 
  11.     bzero(&servaddr,sizeof(servaddr)); 
  12.     servaddr.sin_family = AF_INET; 
  13.     servaddr.sin_port = htons(13); 
  14.     if( inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0) 
  15.         err_quit("inet_pton error for %s .",argv[0]); 
  16.     if(connect(socketfd,(SA*)&servaddr,sizeof(servaddr))<0) 
  17.         err_sys("connecting error."); 
  18.     while( (n = read(socketfd,recvline,MAXLINE))>0){ 
  19.         recvline[n] = 0; 
  20.         if(fputs(recvline,stdout) == EOF) 
  21.             err_sys("read error"); 
  22.     } 
  23.     if(n<0) 
  24.         err_sys("read error"); 
  25.     return 0; 

         编译运行:


  1. $gcc server.c -o server -lunp 
  2. $gcc client.c -o client -lunp 
  3. $./server & 
  4. $./client 192.168.101.71 
  5. Mon Jul 16 17:37:45 2012 
  6. $./client 192.168.101.71 
  7. Mon Jul 16 17:37:47 2012 
  8. $./client 192.168.101.71 
  9. Mon Jul 16 17:37:47 2012 
  10. $./client 192.168.101.71 
  11. Mon Jul 16 17:37:49 2012  

      在读的时候有一个小技巧,就是使用循环的方式去读套接口中的数据而不是只读一次,这是由于需要的数据可能分成多节传过来。下面的代码将展示这一点:


  1. #include "../unp.h" 
  2.  
  3. int main(int argc,char *argv[]) 
  4.     int socketfd,n; 
  5.     char recvline[MAXLINE+1]; 
  6.     struct sockaddr_in servaddr; 
  7.     if(argc != 2) 
  8.         err_quit("Usage:%s <IP Address>",argv[0]); 
  9.     if( (socketfd = socket(AF_INET,SOCK_STREAM,0)) <0 ) 
  10.         err_sys("socket error"); 
  11.     bzero(&servaddr,sizeof(servaddr)); 
  12.     servaddr.sin_family = AF_INET; 
  13.     servaddr.sin_port = htons(13); 
  14.     if( inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0) 
  15.         err_quit("inet_pton error for %s .",argv[0]); 
  16.     if(connect(socketfd,(SA*)&servaddr,sizeof(servaddr))<0) 
  17.         err_sys("connecting error."); 
  18.     int counter = 0; 
  19.     while( (n = read(socketfd,recvline,MAXLINE))>0){ 
  20.         recvline[n] = 0; 
  21.         if(fputs(recvline,stdout) == EOF) 
  22.             err_sys("read error"); 
  23.         counter++; 
  24.     } 
  25.     printf("read operation :%d\n",counter); 
  26.     if(n<0) 
  27.         err_sys("read error"); 
  28.     return 0; 

        在循环中加入计数代码,用来统计计数的次数。然后我们将服务器端的代码改为for循环的形式:


  1. #include "../unp.h" 
  2.  
  3. #include<string.h> 
  4. int main(int argc,char *argv[]) 
  5.     int listenfd,connfd; 
  6.     struct sockaddr_in servaddr; 
  7.     char buff[MAXLINE]; 
  8.     time_t ticks; 
  9.     listenfd = Socket(AF_INET,SOCK_STREAM,0); 
  10.     bzero(&servaddr,sizeof(servaddr)); 
  11.     servaddr.sin_family = AF_INET; 
  12.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
  13.     servaddr.sin_port=htons(13); 
  14.     Bind(listenfd,(SA*)&servaddr,sizeof(servaddr)); 
  15.     Listen(listenfd,LISTENQ); 
  16.     for(;;) 
  17.     { 
  18.         connfd = Accept(listenfd,(SA*)NULL,NULL); 
  19.         ticks = time(NULL); 
  20.         snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks)); 
  21.         int i = 0; 
  22.         int len = strlen(buff); 
  23.         for(i=0;i<len;i++) 
  24.             Write(connfd,&buff[i],sizeof(char)); 
  25.         Close(connfd); 
  26.     } 
  27.     return 0; 

        下面为运行效果:

         


  1. $ ./client 192.168.101.71 
  2. Mon Jul 16 21:24:05 2012 
  3. read operation :4 
  4. $ ./client 192.168.101.71 
  5. Mon Jul 16 21:24:05 2012 
  6. read operation :4 
  7. $ ./client 192.168.101.71 
  8. Mon Jul 16 21:24:05 2012 
  9. read operation :3 
  10. $ ./client 192.168.101.71 
  11. Mon Jul 16 21:24:06 2012 
  12. read operation :4 
  13. $ ./client 192.168.101.71 
  14. Mon Jul 16 21:24:06 2012 
  15. read operation :3 
  16. $ ./client 192.168.101.71 
  17. Mon Jul 16 21:24:07 2012 
  18. read operation :5 

 


本文转自hipercomer 51CTO博客,原文链接:http://blog.51cto.com/hipercomer/932671


上一篇:C++上机实验二:派生类的设计与使用


下一篇:微信jssdk分享链接给好友,图标只能自己看到,对方看不到!