c++select函数的使用案例
c++中的select函数可以实现多路复用的网络通信,用于监听多个文件描述符,一旦其中任意一个文件描述符发生了连接就可以对其进行处理。下面是一个简单的使用案例:
```
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>recv函数
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <cstring>
using namespace std;
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
cerr << "Failed to create socket." << endl;
return -1;
}
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //设置非阻塞
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_port = htons(8181);
bind(sockfd, (struct sockaddr *)&local, sizeof(local));
listen(sockfd, 100); //监听客户端连接
int maxfd = sockfd;
fd_set readfds, allfds;
FD_ZERO(&allfds);
FD_SET(sockfd, &allfds); //添加sockfd到监视列表
while (true) {
readfds = allfds; //要监视的文件描述符列表
select(maxfd + 1, &readfds, NULL, NULL, NULL);
//有客户端连接时处理连接请求
if (FD_ISSET(sockfd, &readfds)) {
struct sockaddr_in client; //客户端地址
socklen_t len = sizeof(client);
int clientfd = accept(sockfd, (struct sockaddr *)&client, &len);
if (clientfd >= 0) {
cout << "New client connected from " << inet_ntoa(client.sin_addr) << endl;
FD_SET(clientfd, &allfds); //将客户端sockfd添加到监视列表
if (clientfd > maxfd) maxfd = clientfd;
}
}
//处理客户端数据请求
for (int i = sockfd + 1; i <= maxfd; i++) {
if (FD_ISSET(i, &readfds)) {
char buf[1024] = {0};
int n = recv(i, buf, sizeof(buf), 0);
if (n > 0) {
cout << "Received data from client " << i << ": " << buf << endl;
} else {
//客户端断开连接
cout << "Client " << i << " disconnected." << endl;
close(i);
FD_CLR(i, &allfds); //将客户端sockfd从监视列表中删除
}
}
}
}
close(sockfd);
return 0;
}
```
在上述代码中,使用了FD_ZERO、FD_SET、FD_ISSET、FD_CLR等select函数的相关宏定义。在这个例子中,select函数的主要作用是在while循环中监视socketfd和客户端socketfd的数据请求,并处理连接请求和数据请求。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论