【答案】:
UDP也可以使用select/epoll,但是,通常没有这个必要。Richard Stevens在不朽的经典《Unix网络编程卷一》中已经说了:“大多数情况下,TCP服务器是并发的,UDP的服务器是迭代的。”说白了,UDP没有必要使用多路复用。
【网络编程模型(伪代码)】:
1. TCP(多路复用模型):
1 srv_sock = create(); 2 bind(srv_sock, srv_addr); 3 listen(srv_sock, max_connections); //设定最大连接数 4 fd_set myset; 5 max_fd = srv_sock; 6 while (1) 7 { 8 FD_ZERO(&myset); 9 select(max_fd+1, &myset); //注意,myset是输出参数,不是输入参数 10 for (fd = 0; fd < max_fd; ++fd) 11 { 12 if (FD_ISSET(myset, fd)) 13 { 14 if (fd == srv_sock) //1. 新连接 15 { 16 cli_sock = accept(srv_sock); 17 max_fd = max(max_fd, cli_sock); 18 } 19 else //2. 连接可读 20 { 21 recv(fd); //TCP使用recv 22 } 23 } 24 } 25 }
2. UDP(迭代模型):
1 srv_sock = create(); 2 bind(srv_sock, srv_addr); 3 while (1) 4 { 5 int ret = recvfrom(srv_sock, &client_addr); //UDP使用recvfrom;注意,client_addr是输出参数,不是输入参数 6 ... ... 7 }
【参考】
1. 《Unix网络编程卷一》. 22.7节 UDP并发服务器. Richard Stevens
2. 《Unix网络编程卷一》. 第8章 UDP网络编程. Richard Stevens