1.配置环境
在这里下载unpv13e.tar.gz,其中包含了《UNIX网络编程》第一卷的源代码。假设将其移到~/Unix/Network/目录下,以下为配置过程(假设当前目录为下载目录):
- mv ./unpv13e.tar.gz ~/Unix/Network
- cd ~/Unix/Network
- tar -zxvf unpv13e.tar.gz
- cd unpv13e
- ./configure
- cd lib
- make
- cd ../ #back to unpv13e/
- cp libunp.a /usr/lib
- cp libunp.a /usr/lib64
- cd ../ #back to Network/
- cp ./unpv13e/lib/unp.h ./
- cp ./unpv13e/config.h ./
- vi unp.h #使用vi将unp.h中的 #include "../config.h"改为#include "./config.h"
- mkdir timer_server
- cd timer_server
2.编写代码
编写服务端代码:
- #include "../unp.h"
- int main(int argc,char *argv[])
- {
- int listenfd,connfd;
- struct sockaddr_in servaddr;
- char buff[MAXLINE];
- time_t ticks;
- listenfd = Socket(AF_INET,SOCK_STREAM,0);
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port=htons(13);
- Bind(listenfd,(SA*)&servaddr,sizeof(servaddr));
- Listen(listenfd,LISTENQ);
- for(;;)
- {
- connfd = Accept(listenfd,(SA*)NULL,NULL);
- ticks = time(NULL);
- snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));
- Write(connfd,buff,strlen(buff));
- Close(connfd);
- }
- return 0;
- }
编写客户端代码:
- #include "../unp.h"
- int main(int argc,char *argv[])
- {
- int socketfd,n;
- char recvline[MAXLINE+1];
- struct sockaddr_in servaddr;
- if(argc != 2)
- err_quit("Usage:%s <IP Address>",argv[0]);
- if( (socketfd = socket(AF_INET,SOCK_STREAM,0)) <0 )
- err_sys("socket error");
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(13);
- if( inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)
- err_quit("inet_pton error for %s .",argv[0]);
- if(connect(socketfd,(SA*)&servaddr,sizeof(servaddr))<0)
- err_sys("connecting error.");
- while( (n = read(socketfd,recvline,MAXLINE))>0){
- recvline[n] = 0;
- if(fputs(recvline,stdout) == EOF)
- err_sys("read error");
- }
- if(n<0)
- err_sys("read error");
- return 0;
- }
编译运行:
- $gcc server.c -o server -lunp
- $gcc client.c -o client -lunp
- $./server &
- $./client 192.168.101.71
- Mon Jul 16 17:37:45 2012
- $./client 192.168.101.71
- Mon Jul 16 17:37:47 2012
- $./client 192.168.101.71
- Mon Jul 16 17:37:47 2012
- $./client 192.168.101.71
- Mon Jul 16 17:37:49 2012
在读的时候有一个小技巧,就是使用循环的方式去读套接口中的数据而不是只读一次,这是由于需要的数据可能分成多节传过来。下面的代码将展示这一点:
- #include "../unp.h"
- int main(int argc,char *argv[])
- {
- int socketfd,n;
- char recvline[MAXLINE+1];
- struct sockaddr_in servaddr;
- if(argc != 2)
- err_quit("Usage:%s <IP Address>",argv[0]);
- if( (socketfd = socket(AF_INET,SOCK_STREAM,0)) <0 )
- err_sys("socket error");
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(13);
- if( inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)
- err_quit("inet_pton error for %s .",argv[0]);
- if(connect(socketfd,(SA*)&servaddr,sizeof(servaddr))<0)
- err_sys("connecting error.");
- int counter = 0;
- while( (n = read(socketfd,recvline,MAXLINE))>0){
- recvline[n] = 0;
- if(fputs(recvline,stdout) == EOF)
- err_sys("read error");
- counter++;
- }
- printf("read operation :%d\n",counter);
- if(n<0)
- err_sys("read error");
- return 0;
- }
在循环中加入计数代码,用来统计计数的次数。然后我们将服务器端的代码改为for循环的形式:
- #include "../unp.h"
- #include<string.h>
- int main(int argc,char *argv[])
- {
- int listenfd,connfd;
- struct sockaddr_in servaddr;
- char buff[MAXLINE];
- time_t ticks;
- listenfd = Socket(AF_INET,SOCK_STREAM,0);
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port=htons(13);
- Bind(listenfd,(SA*)&servaddr,sizeof(servaddr));
- Listen(listenfd,LISTENQ);
- for(;;)
- {
- connfd = Accept(listenfd,(SA*)NULL,NULL);
- ticks = time(NULL);
- snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));
- int i = 0;
- int len = strlen(buff);
- for(i=0;i<len;i++)
- Write(connfd,&buff[i],sizeof(char));
- Close(connfd);
- }
- return 0;
- }
下面为运行效果:
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:05 2012
- read operation :4
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:05 2012
- read operation :4
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:05 2012
- read operation :3
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:06 2012
- read operation :4
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:06 2012
- read operation :3
- $ ./client 192.168.101.71
- Mon Jul 16 21:24:07 2012
- read operation :5
本文转自hipercomer 51CTO博客,原文链接:http://blog.51cto.com/hipercomer/932671