非阻塞套接字即使没有明确地将它们设置为非阻塞也是如此

时间:2013-12-05 10:09:36

标签: c++ sockets tcp blocking nonblocking

我有一个用C ++编写的TCP应用程序,客户端和服务器交换数据。我已经确定了一个套接字,认为它默认会被阻塞;相反,在服务器等待客户端之后,我让该客户端调用recv函数而不等待数据。这是我在客户端中对套接字进行初始化的代码。

int TCPreceiver::initialize(char* address, int port)
{
    sock = socket (AF_INET, SOCK_STREAM, 0);
    cout << "Socket: " << sock << endl;
    sockaddr_in target;
    target.sin_family = AF_INET;
    target.sin_port = htons (port);
    target.sin_addr.s_addr = inet_addr(address);

    int fails=0;
    while (connect(sock, (sockaddr*) &target, sizeof(target)) == -1)
    {
        fails++;
        if (fails==10)
        {
            close(sock);
            cout << "Error with connection to the server, try again"<< endl;
            exit(-1);
        }
    }

    cout << "Client connected (control channel)" << endl;

    unsigned char text[10]; //Request message
    //fill text[]
    if(send(sock, (char*)text, 10, 0)==-1)
    {
            printf("send() failed with error code : %d" , -1);
            exit(EXIT_FAILURE);
    }

    return 0;
}

我尝试添加此代码:

int opts;
opts = fcntl(sock,F_GETFL);
if (opts < 0) {
    perror("fcntl(F_GETFL)");
    exit(0);
}
opts = (opts & (~O_NONBLOCK));
if (fcntl(sock,F_SETFL,opts) < 0) {
    perror("fcntl(F_SETFL)");
    exit(0);
}

但它仍然不起作用,如果我调用recv(),应用程序不会阻塞(并且recv()总是返回0)。这是我调用recv()的函数:

void TCPreceiver::receive(char* text, int& dim)
{
    int ret;

    ret = recv(sock, text, dim, 0);
    dim=ret;
    if(ret == -1){
        printf("recv() failed with error (%d)\n", ret);
        //system("PAUSE");
        exit(1);
    }
}

我哪里错了?

1 个答案:

答案 0 :(得分:3)

recv()返回零表示(1)你传递了一个零长度,这只是一个编程错误,我在这里不再讨论,或者(2)流结束。对等已关闭连接。这不是非阻塞情况,这是连接的结束。您必须关闭套接字并停止使用它。它永远不会返回任何东西。它再次归零。

请参阅 man 页面。