如何检测我是否有东西要从套接字读取?(c++)
我想从客户那里得到一定数量的回答。我怎么能这么做?我是说我有那个密码如何检测我是否有东西要从套接字读取?(c++),c++,sockets,C++,Sockets,我想从客户那里得到一定数量的回答。我怎么能这么做?我是说我有那个密码 unsigned secondsElapsed = 0; while(secondsElapsed <= TIMER){ char tBuffer[32]; if (recv(clientSocket, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) == 0){ myPlayer->dcPlayer(
unsigned secondsElapsed = 0;
while(secondsElapsed <= TIMER){
char tBuffer[32];
if (recv(clientSocket, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) == 0){
myPlayer->dcPlayer();
\\ More stuff to do if player is dissconected
\\ But if is not dc, and is typing, how can i check my socket to see
\\ if i have an answer there to read, else i`ll increment
\\ secondsElapsed until is equal to TIMER or until i get an answer
\\ from my client.
usleep(1000000);
secondsElapsed++;
}
所以,问题是:我如何检查我的客户是否给我回复?如果我尝试读取,那么我的程序将被卡住,并且我将无法增加secondsElapsed。这里有许多选项。首先,您可能会使用非阻塞套接字(通常不是很好的解决方案)。更好的选择是使用操作系统提供的轮询/异步通知机制-例如,on*Nix用户可以从select、poll和epoll中进行选择,而Windows有自己的异步事件通知API,例如,I/O完成端口,如下所述:这里有许多选项。首先,您可能会使用非阻塞套接字(通常不是很好的解决方案)。更好的选择是使用操作系统提供的轮询/异步通知机制-例如,on*Nix用户可以从select、poll和epoll中进行选择,而Windows有自己的异步事件通知API,例如I/O完成端口,此处描述:在调用recv或read读取数据之前,您可以在*Nix系统上使用select或pselect或epoll来了解数据何时可用,例如:
char tBuffer[32];
float secondsElapsed = 0;
clock_t start = clock(), end;
do {
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(clientSocket, &rfd);
struct timeval timeout;
timeout.tv_sec = TIMER - secondsElapsed;
timeout.tv_usec = 0;
int ret = select(clientSocket+1, &rfd, NULL, NULL, &timeout);
if (ret == -1) {
myPlayer->dcPlayer();
break;
}
if (ret == 0) {
// timeout ...
break;
}
// data available, read it...
ret = recv(clientSocket, tBuffer, sizeof(tBuffer), 0);
if (ret <= 0) {
myPlayer->dcPlayer();
break;
}
// use tBuffer up to ret number of bytes...
if (... /*no more data is expected*/) {
break;
}
end = clock();
secondsElapsed = end - start; // time difference is now a float
seconds /= CLOCKS_PER_SEC; // this division is now floating point
}
while (secondsElapsed <= TIMER);
在调用recv或read读取数据之前,您可以使用select或pselect或epoll on*Nix系统来了解数据何时可用,例如:
char tBuffer[32];
float secondsElapsed = 0;
clock_t start = clock(), end;
do {
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(clientSocket, &rfd);
struct timeval timeout;
timeout.tv_sec = TIMER - secondsElapsed;
timeout.tv_usec = 0;
int ret = select(clientSocket+1, &rfd, NULL, NULL, &timeout);
if (ret == -1) {
myPlayer->dcPlayer();
break;
}
if (ret == 0) {
// timeout ...
break;
}
// data available, read it...
ret = recv(clientSocket, tBuffer, sizeof(tBuffer), 0);
if (ret <= 0) {
myPlayer->dcPlayer();
break;
}
// use tBuffer up to ret number of bytes...
if (... /*no more data is expected*/) {
break;
}
end = clock();
secondsElapsed = end - start; // time difference is now a float
seconds /= CLOCKS_PER_SEC; // this division is now floating point
}
while (secondsElapsed <= TIMER);
查找poll,select,epoll,可能还有一个基本的网络教程。查找poll,select,epoll,可能还有一个基本的网络教程。对于windows,我将使用您提到的异步事件通知API:@Moo Juice,谢谢,将合并。我的Windows非常弱。选择在Windows上可用。如果代码需要阻止等待读取完成,那么IOCP就太过分了。@RemyLebeau有点同意,但我从OP那里得到了一个概念,认为阻止是不可取的:对于windows,我会使用你提到的异步事件通知API:@Moo Juice,谢谢,将合并它。我的Windows非常弱。选择在Windows上可用。如果代码需要阻塞等待读取完成,那么IOCP就太过分了。@RemyLebeau有些同意,但我从OP那里得到了一个概念,阻塞是不可取的: