0

全て :)

LinuxとWinXPで正しく動作するコードがいくつかあります

int FlowTestIP::do_recvfrom()
{
    int ret;
    struct timeval timeout;// = {2, 0};
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    fd_set rfds;
    while(running) {
            FD_ZERO(&rfds);
            FD_SET(m_socket, &rfds);
            ret = select(m_socket + 1, &rfds, 0, 0, &timeout);
            cout << "// select ret = " << ret << " (errno = " << errno << ")" << endl;
            if (ret == -1 || ret == 0) {
                    if (!(ret == 0 && errno == 0))
                            cout << "select ret = " << ret << " (errno = " << errno << ")" << endl;
                    return ret;
            }
            if (FD_ISSET(m_socket, &rfds)) {
                    cout << WSAGetLastError() << endl;
                    break;
            }
    }
    return recvfrom(m_socket, in_buf, mtu, 0, (struct sockaddr *)&si_other, (socklen_t *)&otherAddrSize);
}

ただし、Windows 7では、クライアントアプリケーションが終了しても、inはループし続けます。悪い出力は

...
// ret = 1(errno = 0)
0
//を選択ret= 1(errno = 0)
0
//を選択ret= 1(errno = 0)
0
FTControlServerThread :: run
FTControlServerThread ::
receive pkt-> ft_tos = UCHAR_MAX
QFuture :: waitForFinished()
client alive true
// ret = 1(errno = 0)
0
//を選択ret= 1(errno = 0)
0
// ret = 1(errno = 0)
0 を選択

通常(WinXPおよびLinuxの場合)出力は次のようになります

...
// ret = 1(errno = 0)
0
//を選択ret= 1(errno = 0)
0
//を選択ret= 1(errno = 0)
0
FTControlServerThread :: run
FTControlServerThread ::
receive pkt-> ft_tos = UCHAR_MAX
QFuture :: waitForFinished()
client alive true
QFuture :: finish

そしてそれが私が待っていることです。

誰かがそのような不正行為に遭遇したことがありますか?

前もって感謝します!

PS @JoachimPileborgが、この関数をどのように呼び出すかを示すように求めました。

FlowTest::recv(char *payload, size_t size)  
{  
...  
    while (running) {  
        len = do_recvfrom(); // it virtual method of class FlowTest  
        if (len == -1 || len == 0) {  
            return len;  
        }  

        if (running && !transport_recv_helper()) {  
            continue;  
        } else {  
            break;  
        }  
    }  
...  
}  

そしてrecvはサーバーGUIから呼び出されます

void FlowTestServer::runTest(FlowTestServerHelper handler)
{
...
        if ((ret = server->recv(rcvdData, (size_t *)&size)) == -1 || ret == 0 || size == 0) {
            if (server_busy == 0)
                break;
            cout << "can't receive data (size == " << size << "; ret = " << ret << ")" << endl;
            continue;
        }
...
}
4

1 に答える 1

2

まず、を使用coutするとリセットできerrnoます。通常はそうではありませんが、特にロケールを設定する必要がある場合の最初の使用では可能です。errnoの値を一時変数に保存するか、andfriendsを使用する必要がありますfprintf。Clib関数としてPOSIXがその動作を制御します。

WSAGetLastError()第二に:Windowsでは、 notを使用する必要がありますerrno

Linux/unixおよびWindowsで使用できるマクロsock_errnoを作成することをお勧めします。これにより、プラットフォームに依存しない方法でコーディングできるようになります。(errno)(WSAGetLastError())

于 2013-01-07T13:02:09.983 に答える