面试题答案
一键面试#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include <sys/select.h>
#define BUFFER_SIZE 1024
int main() {
int sock1 = socket(AF_INET, SOCK_STREAM, 0);
int sock2 = socket(AF_INET, SOCK_STREAM, 0);
// 假设sock1和sock2已经被正确初始化和连接
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(sock1, &read_fds);
FD_SET(sock2, &read_fds);
char buffer[BUFFER_SIZE];
while (true) {
fd_set tmp_fds = read_fds;
int activity = select(std::max(sock1, sock2) + 1, &tmp_fds, nullptr, nullptr, nullptr);
if (activity < 0) {
std::cerr << "select error" << std::endl;
break;
} else if (activity > 0) {
if (FD_ISSET(sock1, &tmp_fds)) {
int bytesRead = recv(sock1, buffer, sizeof(buffer), 0);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
std::cout << "Data from sock1: " << buffer << std::endl;
}
}
if (FD_ISSET(sock2, &tmp_fds)) {
int bytesRead = recv(sock2, buffer, sizeof(buffer), 0);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
std::cout << "Data from sock2: " << buffer << std::endl;
}
}
}
}
close(sock1);
close(sock2);
return 0;
}
上述代码中:
- 首先创建了两个套接字
sock1
和sock2
,假设它们已经正确初始化和连接。 - 使用
fd_set
来管理要监听的文件描述符集合,并使用FD_ZERO
、FD_SET
初始化集合。 - 在
while
循环中,使用select
函数监听文件描述符集合中的可读事件。 - 根据
select
的返回值,判断哪个套接字有可读事件,并通过recv
函数接收数据并输出。 - 最后关闭两个套接字。
注意,在实际应用中,需要处理更多的错误情况,如套接字创建、绑定、连接错误等,以及可能的内存管理和资源释放问题。同时,上述代码基于类Unix系统,在Windows系统上需要使用WSASelect
等Windows特定的函数。