2. 基于多路复用的服务端
Posted 阿龙亡命天涯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2. 基于多路复用的服务端相关的知识,希望对你有一定的参考价值。
当有客户端连接时再调用accept()接受连接
监视服务端文件描述符server_fd,有事件发生,连接:accept(),返回新的文件描述符:client_fd与客户端通信,监听这个描述符,监听的事件:数据是否到达,若发生了就调用read/recv函数处理数据。
理解:
文件描述符在[0,max]中,都会被监视。如果监视的文件描述符发生了事件,返回大于0的数值,进入if语句,遍历文件描述符,查找哪一个发生了。如果是服务端的事件,处理,接受客户端连接。不是服务端的事件,那就是客户端的事件:读数据。
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
//处理服务端的事件函数
int server_handler(int server)
struct sockaddr_in addr = 0;
socklen_t asize = sizeof(addr);
return accept(server, (struct sockaddr*)&addr, &asize);
//处理客户端数据的事件
int client_handler(int client)
char buf[32] = 0;
int ret = read(client, buf, sizeof(buf)-1);
if( ret > 0 )
buf[ret] = 0;
printf("Receive: %s\\n", buf);
if( strcmp(buf, "quit") != 0 )
ret = write(client, buf, ret);
else
ret = -1;
return ret;
int main()
int server = 0;
struct sockaddr_in saddr = 0;
int max = 0;
int num = 0;
fd_set reads = 0;
fd_set temps = 0;
struct timeval timeout = 0;
server = socket(PF_INET, SOCK_STREAM, 0);
if( server == -1 )
printf("server socket error\\n");
return -1;
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(8888);
if( bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1 )
printf("server bind error\\n");
return -1;
if( listen(server, 1) == -1 )
printf("server listen error\\n");
return -1;
printf("server start success\\n");
FD_ZERO(&reads);//清空
FD_SET(server, &reads);//标识,对serevr监听
max = server;
while( 1 )
temps = reads;
//设置超时值
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
num = select(max+1, &temps, 0, 0, &timeout);//最大值基础上+1
if( num > 0 )//进入if语句说明有事件发生,接下来查找哪一个事件并处理
int i = 0;
for(i=1; i<=max; i++)
if( FD_ISSET(i, &temps) )//当前是否为有事件发生的文件描述符
if( i == server )//是否为server,说明有新客户端连接
int client = server_handler(server);
if( client > -1 )
FD_SET(client, &reads);
max = (client > max) ? client : max;
printf("accept client: %d\\n", client);
else//客户端,有数据需要处理
int r = client_handler(i);
if( r == -1 )
FD_CLR(i, &reads);
close(i);
close(server);
return 0;
印证了Linux一切皆文件的说法!
是否还有优化空间,select是否可以优化?
以上是关于2. 基于多路复用的服务端的主要内容,如果未能解决你的问题,请参考以下文章