这是我到目前为止的代码,我基本上有一个fd sock_comm
,它是监听套接字,然后将建立并添加多个客户端套接字连接。我需要能够接受新连接,但也可以接收现有连接,因此我使用select
。我在尝试迭代while循环意外重启的现有连接时遇到了问题。
int n = sock_comm+1;
int max_sock;
while (1) {
max_sock = n;
printf("sock_comm: %d\n", sock_comm);
// Clear the fd_set and add back connections
FD_ZERO(&readfds);
for (int i=sock_comm; i < max_sock; i++) {
FD_SET(i, &readfds);
}
select(n, &readfds, NULL, NULL, NULL);
printf("max socket: %d\n", max_sock);
fd = sock_comm;
// Iterate through each connection
while (fd < max_sock) {
printf("fd: %d\n", fd);
printf("sock_comm2: %d\n", sock_comm);
// If activity on current connection
if (FD_ISSET(fd, &readfds)) {
printf("Connection on %d\n", fd);
// If connection on listener, accept
if (fd == sock_comm) {
if ((new_s = accept(sock_comm, (struct sockaddr *)&client_addr, &len)) < 1) {
perror("tcpserver: accept");
exit(1);
}
n++;
client_info.sockid = new_s;
// Join handler thread
pthread_create(&threads[0],NULL,join_handler,&client_info);
pthread_join(threads[0],&exit_value);
printf("sock_comm3: %d\n", sock_comm);
} else {
// Create and join thread for receiving data
}
}
fd++;
printf("sock_comm4: %d\n", sock_comm);
}
}
我希望初始连接后的输出是这样的:
sock_comm: 3
max socket: 4
fd: 3
sock_comm2: 3
Connection on 3
sock_comm3: 3
sock_comm4: 3
sock_comm: 3
然后选择过程再次开始。发生的事情是这样的:
sock_comm: 3
max socket: 4
fd: 3
sock_comm2: 3
Connection on 3
sock_comm3: 3
sock_comm4: 3
fd: 1
sock_comm2: 3
sock_comm4: 3
fd: 2
sock_comm2: 3
sock_comm4: 3
fd: 3
sock_comm2: 3
Connection on 3
正如您所看到的,while (fd < max_sock)
循环正在重置,并以某种方式从1开始,但fd
永远不应该低于3.我不知道我的代码有什么问题,它是否必须要做在循环中使用select
?我之前从未使用它,但它导致奇怪的行为。当没有什么可以接受时,它会陷入接受状态。
加入处理程序:
void *join_handler(struct global_table *rec) {
int newsock;
struct packet packet_reg;
newsock = rec->sockid;
for (int i=0; i < REQUEST_NO; i++) {
if (recv(newsock, &packet_reg, sizeof(packet_reg), 0) < 1) {
printf("Could not receive RG-%d\n", i+1);
exit(1);
} else {
printf("Registered received: %s\n",packet_reg.data);
}
}
// add to table
pthread_mutex_lock(&my_mutex);
counter++;
record[counter].sockid = newsock;
pthread_mutex_unlock(&my_mutex);
// send response acknowledging registration
packet_reg.type = htons(221);
sprintf(packet_reg.data, "%d", newsock);
if(send(newsock, &packet_reg, sizeof(packet_reg), 0) < 1) {
printf("ACK send failed\n");
exit(1);
}
pthread_exit(NULL);
}