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