极速多用户网页音乐播放器(框架固定形式/底部音乐播放器)
<div><p>此网页使用了框架,但您的浏览器不支持框架。</p></div>

使用Select编写多客户连接的网络服务器

select系统条用允许程同时在多个底层文件描述符上等待输入的到达(或输出的完成)。

一般在linux系统上,标准输入的文件描述符是0;标准输出的文件描述符是1;

标准错误的文件描述符是2;

在Posix定义分别定义为:STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO

他们都包含在unistd.h头文件中

以下代码对于并发连接并不能够同时处理,可以在数据处理部分起多线程处理

服务器端代码如下(客户端代码不做修改):

View Code
 1 #include <sys/types.h>
 2 #include <sys/socket.h>
 3 #include <iostream>
 4 #include <netinet/in.h>
 5 #include <sys/time.h>
 6 #include <sys/ioctl.h>
 7 #include <unistd.h>
 8 #include <stdlib.h>
 9 #include <arpa/inet.h>
10 #include <string.h>
11 
12 using namespace std;
13 
14 const string SERVER_IP = "192.168.1.105";
15 const short SERVER_PORT = 9527;
16 const int MAX_CONN_NUM = 5;
17 const int MAX_DATA_LENGTH = 255;
18 
19 
20 int main(int argc, char** argv)
21 {
22     int server_sockfd, client_sockfd;
23     int server_len, client_len;
24     struct timeval timeout;
25     struct sockaddr_in server_address;
26     struct sockaddr_in client_address;
27     int result;
28     fd_set readfds, testfds;
29     char ch[MAX_DATA_LENGTH] = {0};
30 
31     timeout.tv_sec = 2;
32     timeout.tv_usec = 500000;
33 
34     server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
35 
36     server_address.sin_family = AF_INET;
37     server_address.sin_addr.s_addr = inet_addr(SERVER_IP.c_str());
38     server_address.sin_port = htons(SERVER_PORT);
39     server_len = sizeof(server_address);
40 
41     bind(server_sockfd, (struct sockaddr*)&server_address, server_len);
42 
43     listen(server_sockfd, MAX_CONN_NUM);
44 
45     FD_ZERO(&readfds);
46     FD_SET(server_sockfd, &readfds);
47 
48     while(1)
49     {
50         int fd;
51         int nread;
52 
53         testfds = readfds;
54 
55         cout << "server waiting..." << std::endl;
56         result = select(FD_SETSIZE, &testfds, (fd_set*)0, (fd_set*)0, &timeout); // 此处可以设超时时间为(struct timeval*)0,一般设置为0无限期阻塞
57  
58         if (result < 1)
59         {
60             cerr << "select failed!" << endl;
61             exit(EXIT_FAILURE);
62         }
63 
64         for (fd = 0; fd < FD_SETSIZE; fd++)
65         {
66             if (FD_ISSET(fd, &testfds))
67             {
68                 if (fd == server_sockfd)
69                 {
70                     client_len = sizeof(client_address);
71                     client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, (socklen_t*)&client_len);
72                     FD_SET(client_sockfd, &readfds);
73                     cout << "adding client on fd " << client_sockfd << endl;
74                 } 
75                 else
76                 {
77                     ioctl(fd, FIONREAD, &nread);
78 
79                     if (nread == 0)
80                     {
81                         close(fd);
82                         FD_CLR(fd, &readfds);
83                         cout << "removing client on fd " << fd << endl; 
84                     }
85                     else
86                     {
87                         read(fd, ch , MAX_DATA_LENGTH);
88                         cout << "serving client on fd " << fd << endl;
89                         cout << "receive from client is " << ch << std::endl;
90                         strncpy(ch, "Hello Client", MAX_DATA_LENGTH);
91                         write(fd, ch, MAX_DATA_LENGTH);
92                         sleep(5);
93                     }
94                 }
95             }
96         }
97     }
98     close(server_sockfd);
99 }

 

posted @ 2013-04-15 21:03  飞鼠溪  阅读(166)  评论(0编辑  收藏  举报