我一定是在设置 select()
和 write_fds
时做错了什么。目前,当我第一次调用 sendData()
时,它会从缓冲区发送 117 个字节(全部)。然后立即再次调用它,即使缓冲区中没有更多数据要发送,它也会一直调用 sendData()
。
知道我在这里做错了什么吗?
int readData(int j){
return recv(j, buf , nbytes , 0);
}
int sendData(int j){
unsigned v = fcntl(j, F_GETFL, 0);
fcntl(j, F_SETFL, v | O_NONBLOCK);
return send(j, buf, nbytes, 0);
}
fd_set master;
fd_set read_fds;
fd_set write_fds;
int fdmax;
...
FD_ZERO(&master);
FD_SET(socket, &master);
fdmax = socket;
for(;;){
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
read_fds = master;
write_fds = master;
if(select(fdmax+1, &read_fds, &write_fds, NULL, NULL) == -1){
exit(4);
}
for(i = 0; i <= fdmax; i++){
if(FD_ISSET(i, &read_fds)){
if(i == socket){
// handle new connections
addrlen = sizeof remoteaddr;
newfd = accept(socket, (struct sockaddr *)&addr, &addrlen);
FD_SET(newfd, &master);
if(newfd > fdmax) fdmax = newfd;
}else{
// we got some data from a client
readData(i);
}
} else if(FD_ISSET(i, &write_fds)){
if(i != socket){
// send data when notified
sendData(i);
}
}
}
}
最佳答案
您要求 select 在网络堆栈中有空间发送更多数据时通知您(这就是 write_fds 正在检查的内容)。因为你只写了 117 个字节,所以有足够的空间,所以它立即返回,告诉你写更多的数据。
由于您没有更多数据要发送,您要做的是从 write_fds
集中删除该文件描述符。如果对 send
的调用返回短写(无法写入所有数据)或 EWOULDBLOCK(假设您将其设置为非-阻塞模式)。
这给您的代码带来了主要问题——您在调用 send/recv 时没有检查返回值,因此您不知道实际发送或接收了多少数据。
关于c - 在 C 中设置 select() 和 write_fds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36415680/