- 论坛徽章:
- 0
|
我正在读wrox系例中的Beginning Linux Programming,其中socket编程中,针对select用法所举的例子百思不得其解,特请大家帮忙分析指正。
例子是关于一个服务器程序实现对多个客户同时处理的
server1.c 用fork()实现
server2.c 用select()实现
server1.c 主要代码如下:
- while(1) {
- char ch;
- printf("server waiting\n");
- /* Accept connection. */
- client_len = sizeof(client_address);
- client_sockfd = accept(server_sockfd,
- (struct sockaddr *)&client_address, &client_len);
- /* Fork to create a process for this client and perform a test to see
- whether we're the parent or the child. */
- if(fork() == 0) {
- /* If we're the child, we can now read/write to the client on client_sockfd.
- The five second delay is just for this demonstration. */
- read(client_sockfd, &ch, 1);
- sleep(5);
- ch++;
- write(client_sockfd, &ch, 1);
- close(client_sockfd);
- exit(0);
- }
- /* Otherwise, we must be the parent and our work for this client is finished. */
- else {
- close(client_sockfd);
- }
- }
复制代码
server2.c 主要代码如下:
- FD_ZERO(&readfds);
- FD_SET(server_sockfd, &readfds);
- /* Now wait for clients and requests.
- Since we have passed a null pointer as the timeout parameter, no timeout will occur.
- The program will exit and report an error if select returns a value of less than 1. */
- while(1) {
- char ch;
- int fd;
- int nread;
- testfds = readfds;
- printf("server waiting\n");
- result = select(FD_SETSIZE, &testfds, (fd_set *)0,
- (fd_set *)0, (struct timeval *) 0);
- if(result < 1) {
- perror("server5");
- exit(1);
- }
- /* Once we know we've got activity,
- we find which descriptor it's on by checking each in turn using FD_ISSET. */
- for(fd = 0; fd < FD_SETSIZE; fd++) {
- if(FD_ISSET(fd,&testfds)) {
- /* If the activity is on server_sockfd, it must be a request for a new connection
- and we add the associated client_sockfd to the descriptor set. */
- if(fd == server_sockfd) {
- client_len = sizeof(client_address);
- client_sockfd = accept(server_sockfd,
- (struct sockaddr *)&client_address, &client_len);
- FD_SET(client_sockfd, &readfds);
- printf("adding client on fd %d\n", client_sockfd);
- }
- /* If it isn't the server, it must be client activity.
- If close is received, the client has gone away and we remove it from the descriptor set.
- Otherwise, we 'serve' the client as in the previous examples. */
- else {
- ioctl(fd, FIONREAD, &nread);
- if(nread == 0) {
- close(fd);
- FD_CLR(fd, &readfds);
- printf("removing client on fd %d\n", fd);
- }
- else {
- read(fd, &ch, 1);
- sleep(5);
- printf("serving client on fd %d\n", fd);
- ch++;
- write(fd, &ch, 1);
- }
- }
- }
- }
- }
复制代码
文章的意思是,server2.c 既能借助select()实现server1.c 的及时处理多客户的请求,又避免了server1.c 中有fork()的资源浪费,
问题是:
我看不出server2.c 中的代码实现有任何能 及时处理 多客户请求的地方。
和以下最简单的代码效率是相同的
- listen(server_sockfd, 5);
- while(1) {
- char ch;
- printf("server waiting\n");
- /* Accept a connection. */
- client_len = sizeof(client_address);
- client_sockfd = accept(server_sockfd,
- (struct sockaddr *)&client_address, &client_len);
- /* We can now read/write to client on client_sockfd. */
- read(client_sockfd, &ch, 1);
- ch++;
- write(client_sockfd, &ch, 1);
- close(client_sockfd);
- }
复制代码
大家分析一下,select()的作用到底在哪里?
还有select()一般都用在何处场合? |
|