iOS BSD Socket select
时间: 2023-12-07 16:55:38 浏览: 321
socket模式中的select
在 iOS 中使用 BSD Socket 进行网络编程时,可以使用 select 函数来实现多路复用。
select 函数可以监视多个文件描述符的状态,当其中有文件描述符发生变化时,select 函数就会返回,并且可以通过返回的结果来判断是哪些文件描述符发生了变化。
具体使用步骤如下:
1. 创建 socket。
2. 绑定 socket。
3. 监听 socket。
4. 创建 fd_set 集合,将需要监视的文件描述符加入集合中。
5. 调用 select 函数,等待文件描述符状态变化。
6. 根据 select 函数的返回结果,判断是哪些文件描述符发生了变化。
7. 处理变化的文件描述符。
下面是一个简单的示例代码:
```
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket < 0) {
perror("socket");
return 1;
}
struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listenSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) {
perror("bind");
close(listenSocket);
return 1;
}
if (listen(listenSocket, 5) != 0) {
perror("listen");
close(listenSocket);
return 1;
}
fd_set readFds;
FD_ZERO(&readFds);
FD_SET(listenSocket, &readFds);
while (true) {
fd_set tmpFds = readFds;
int maxFd = listenSocket;
if (select(maxFd + 1, &tmpFds, NULL, NULL, NULL) < 0) {
perror("select");
close(listenSocket);
return 1;
}
for (int i = 0; i <= maxFd; ++i) {
if (FD_ISSET(i, &tmpFds)) {
if (i == listenSocket) {
// 有新的连接请求
struct sockaddr_in clientAddr;
socklen_t addrLen = sizeof(clientAddr);
int clientSocket = accept(listenSocket, (struct sockaddr *)&clientAddr, &addrLen);
if (clientSocket < 0) {
perror("accept");
close(listenSocket);
return 1;
}
printf("New connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
FD_SET(clientSocket, &readFds);
if (clientSocket > maxFd) {
maxFd = clientSocket;
}
} else {
// 有数据可读
char buf[1024];
int len = recv(i, buf, sizeof(buf), 0);
if (len < 0) {
perror("recv");
close(listenSocket);
return 1;
} else if (len == 0) {
printf("Connection closed\n");
close(i);
FD_CLR(i, &readFds);
} else {
buf[len] = '\0';
printf("Received: %s\n", buf);
}
}
}
}
}
return 0;
}
```
这个示例代码实现了一个简单的 TCP 服务器,可以接受客户端的连接,并且当有数据可读时,会打印出来。在主循环中,我们使用 select 函数等待文件描述符状态变化,当有新的连接请求或者有数据可读时,就会通过 if 语句来判断是哪些文件描述符发生了变化,并且进行相应的处理。
阅读全文