1. 程式人生 > >Linux----網路程式設計(I/O複用之select系統呼叫)

Linux----網路程式設計(I/O複用之select系統呼叫)

io_select_ser.c

1.	#include <string.h>
2.	#include <assert.h>
3.	#include <unistd.h>
4.	#include <stdio.h>
5.	#include <stdlib.h>
6.	#include <sys/socket.h>
7.	#include <netinet/in.h>
8.	#include <sys/time.h>
9.	#include <sys/select.h>
10.	
11.	#define MAXFD 10
12.	
13.	//IO_select
14.	void fds_init(int fds[])
15.	{
16.	    int i = 0;
17.	    for(; i<MAXFD; i++)
18.	    {
19.	        fds[i] = -1;
20.	    }
21.	}
22.	
23.	void fds_add(int fds[], int fd)
24.	{
25.	    int i = 0;
26.	    for(; i<MAXFD; i++)
27.	    {
28.	        if(fds[i] == -1)
29.	        {
30.	            fds[i] = fd;
31.	            return;
32.	        }
33.	    }
34.	}
35.	
36.	void fds_del(int fds[], int fd)
37.	{
38.	    int i = 0;
39.	    for(; i<MAXFD; i++)
40.	    {
41.	        if(fds[i] == fd)
42.	        {
43.	            fds[i] = -1;
44.	            return;
45.	        }
46.	    }
47.	}
48.	
49.	int main()
50.	{
51.	    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
52.	    assert(sockfd != -1);
53.	
54.	    struct sockadd_in saddr, caddr;
55.	    memset(&saddr, 0, sizeof(saddr));
56.	    saddr.sin_family = AF_INET;
57.	    saddr.sin_port = htons(6000);
58.	    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
59.	
60.	    int res = bind(sockfd, (struct sockadd*)&saddr, sizeof(saddr));
61.	    assert(res != -1);
62.	
63.	    listen(sockfd, 5);
64.	
65.	    int fds[MAXFD];
66.	    fds_init(fds);
67.	
68.	    fds_add(fds, sockfd);
69.	
70.	    while(1)
71.	    {
72.	        fd_set fdset;
73.	        FD_ZERO(&fdset);
74.	
75.	        int maxfd = -1;
76.	        int i = 0;
77.	        for(; i<MAXFD; i++)
78.	        {
79.	            if(fds[i] == -1)
80.	            {
81.	                continue;
82.	            }
83.	            FD_SET(fds[i], &fdset);
84.	            if(fds[i] > maxfd)
85.	            {
86.	                maxfd = fds[i];//替換到集合裡
87.	            }
88.	        }
89.	        struct timeval tv = {5,0};//超時時間為5s
90.	
91.	        int n = select(maxfd+1, &fdset, NULL, NULL, &tv);//第一個引數描述符最大值+1,tv置為空,阻塞
92.	        if(n == -1)
93.	        {
94.	            printf("select error\n");
95.	            continue;
96.	        }
97.	        else if(n == 0)
98.	        {
99.	            printf("time out\n");
100.	            continue;
101.	        }
102.	        else
103.	        {
104.	            int i = 0;
105.	            for(; i<MAXFD; i++)
106.	            {
107.	                if(fds[i] == -1)
108.	                {
109.	                    continue;
110.	                }
111.	                if(FD_ISSET(fds[i], &fdset)) //是否有資料
112.	                {
113.	                    if(fds[i] == sockfd)
114.	                    {
115.	                        //accept特殊描述符
116.	                        int len = sizeof(caddr);
117.	                        int c = accept(sockfd, (struct sockaddr*)&caddr, &len);
118.	                        if(c < 0)
119.	                        {
120.	                            continue;
121.	                        }
122.	                        printf("accept c = %d\n",c);
123.	                        fds_add(fds, c);
124.	                    }
125.	                    else
126.	                    {
127.	                        //recv普通描述符
128.	                        char buff[128] = {0};
129.	                        int num = recv(fds[i], buff, 127, 0);
130.	                        if(num <= 0)
131.	                        {
132.	                            close(fds[i]);
133.	                            fds_del(fds, fds[i]);
134.	                            printf("one client over!\n");
135.	                        }
136.	                        else
137.	                        {
138.	                            printf("recv(%d) = %s\n",fd[i], buff);
139.	                            send(fds[i], "ok", 2, 0);
140.	                        }
141.	                    }
142.	                }
143.	            }
144.	        }
145.	    }
146.	}

io_select_cli.c

1.	#include <string.h>
2.	#include <assert.h>
3.	#include <unistd.h>
4.	#include <stdio.h>
5.	#include <stdlib.h>
6.	#include <sys/socket.h>
7.	#include <netinet/in.h>
8.	#include <sys/select.h>
9.	
10.	//IO_select
11.	int main()
12.	{
13.	    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
14.	    assert(sockfd != -1);
15.	
16.	    struct sockadd_in saddr;
17.	    memset(&saddr, 0, sizeof(saddr));
18.	    saddr.sin_family = AF_INET;
19.	    saddr.sin_port = htons(6000);
20.	    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
21.	  
22.	    int res = bind(sockfd, (struct sockadd*)&saddr, sizeof(saddr));
23.	    assert(res != -1);
24.	
25.	    while(1)
26.	    {
27.	        char buff[128] = {0};
28.	        printf("input:\n");
29.	        fgets(buff, 128, stdin);
30.	        if(strncmp(buff,"end",3) == 0)
31.	        {
32.	            break;
33.	        }
34.	        send(sockfd, buff, strlen(buff), 0);
35.	        memset(buff, 0, 128);
36.	        recv(sockfd, buff, 127, 0);
37.	        printf("buff = %s\n",buff);
38.	    }
39.	    close(sockfd);
40.	    exit(0);
41.	}  

結果: