《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


相关文章
|
5月前
|
Unix Shell Python
unix高级编程-fork和execve
unix高级编程-fork和execve
26 0
|
5月前
|
Unix Linux 调度
unix编程-fork
unix编程-fork
37 0
|
网络协议 Unix
UNIX网络编程卷1(第三版) 客户/服务器程序示例
UNIX网络编程卷1(第三版) 客户/服务器程序示例
89 0
|
设计模式 Java Unix
Java 网络编程实战(二) - Unix的I/O模型解析
Java 网络编程实战(二) - Unix的I/O模型解析
141 0
Java 网络编程实战(二) - Unix的I/O模型解析
|
网络协议
Unix网络编程常用函数深度解析(干货)
Unix网络编程常用函数深度解析
25302 0
|
Unix 网络协议
unix网络编程str_cli使用epoll实现
unix网络编程str_cli使用epoll实现 unix环境高级编程中也有这个函数,都是为了讲解IO多路转接。从本质上来看epoll就是一个改善了的select和poll,本质没发生任何变化,对于构建在poll,select和epoll上的框架使用者来说,没什么区别。
757 0

相关课程

更多