Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检测我是否有东西要从套接字读取?(c++)_C++_Sockets - Fatal编程技术网

如何检测我是否有东西要从套接字读取?(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那里得到了一个概念,阻塞是不可取的: