Linux下Select用法

      由于时间关系,先将我用的代码写到这里,稍后解释。这里服务器端有两个可能阻塞的描述符:一个是网络的,另一个是来自终端的,用select可以保证无论是客户端还是终端给它发送数据,它都可以处理,当然还有更高效率的实现方式,就是poll和epoll,网上有它们查找过程的不同。这里不赘述。

18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <stdio.h>
22 #define SERVER_PORT 6000
23
24 void UdpRequest(int sockfd,const struct sockaddr_in *add, int len)
25 {
26 int n;
27 char buf[1024] = "Good good study! Up";
28 char recvBuf[1024];
29 while (fgets(buf,1024,stdin)!= NULL) {
30 /*向服务器发送数据*/
31 sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)add,len);
32 memset(recvBuf,0,1024);
33 /*接收回应*/
34 n = recvfrom(sockfd,recvBuf,1024,0,NULL,NULL);
35 recvBuf[n] = '\0';
36 fputs(recvBuf,stdout);
37 memset(buf,0,1024);
38 }
39 }
40
41 int main(int argc, const char *argv[])
42 {
43 int sockfd;
44 struct sockaddr_in addr;
45 if (argc != 2) {
46 fprintf(stderr,"usage:client ipaddr port\n");
47 exit(1);
48 }
49
50 /*创建一个udp 数据报类型套接字 */
51 sockfd = socket(AF_INET,SOCK_DGRAM,0);
52 if (sockfd < 0) {
53 fprintf(stderr,"Socket error\n");
54 exit(1);
55 }
56 bzero(&addr,sizeof(addr));
57
58 addr.sin_family = AF_INET;
59 addr.sin_port = htons(SERVER_PORT);
60
61 if (inet_aton(argv[1],&addr.sin_addr) < 0) {
62 fprintf(stderr,"Inet_aton error");
63 exit(1);
64 }
65 UdpRequest(sockfd,&addr,sizeof(addr));
66 close(sockfd);
67 return 0;
68 }

下面是服务器端:

16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #include <netinet/in.h>
21 #include <sys/socket.h>
22 #define SOCKET_PORT 6000
23 /*作用是回复客户端请求*/
24 void Response(int sockfd)
25 {
26 char msg[1024];
27 struct sockaddr_in clientAddr;
28 int addrlen = sizeof(clientAddr);
29 int actualNum;
30 actualNum = recvfrom(sockfd,msg,1024,0,(struct sockAddr*)&clientAddr,&addrlen);
31 sendto(sockfd,msg,actualNum,0,(struct sockAddr*)&clientAddr,addrlen);
32 }
33
34 int main(void)
35 {
36 fd_set rfds;
37 struct timeval tv;
38 int retval;
39 char buf[256];
40 int sockfd;
41 /*创建socket*/
42 struct sockaddr_in addr;
43 sockfd = socket(AF_INET,SOCK_DGRAM,0);
44 if (sockfd < 0) {
45 fprintf(stderr,"Socket error");
46 exit(1);
47 }
48
49 bzero(&addr,sizeof(addr));
50
51 addr.sin_family = AF_INET;
52 addr.sin_port = htons(SOCKET_PORT);
53 addr.sin_addr.s_addr= htonl(INADDR_ANY);
54 /*为服务器绑定一个端口 */
55 if (bind(sockfd,(struct sockAddr*)&addr,sizeof(addr)) < 0) {
56 fprintf(stderr,"Bind error");
57 exit(1);
58 }
59
60 memset((void*)buf,0,sizeof(char)*256);
61
62 FD_ZERO(&rfds);
63 FD_SET(0, &rfds);
64 FD_SET(sockfd,&rfds);
65
66 tv.tv_sec = 5;
67 tv.tv_usec = 0;
69 while(1)
70 {
71
72 retval = select(sockfd + 1, &rfds, NULL, NULL, &tv);
73 if (retval == -1)
74 perror("select()");
75 else if (retval)
76 {
77 if (FD_ISSET(0,&rfds))
78 {
79 printf("Data is available now.\n");
80 scanf("%s",buf);
81 printf("You input a:%s\n",buf);
82 memset((void*)buf,0,sizeof(char)*256);
83 }
84 else if(FD_ISSET(sockfd,&rfds))
85 {
86 Response(sockfd);
87 }
88 }
89 FD_ZERO(&rfds);
90 FD_SET(0,&rfds);
91 FD_SET(sockfd,&rfds);
92
94 }
95 close(sockfd);
96 return 0;
97 }

    经过测试没有问题,终于可以回去睡觉了。


posted on 2011-11-08 23:34  sprzhing  阅读(422)  评论(0编辑  收藏  举报

导航