recv()套接字循环永远不会结束C.

时间:2013-04-27 20:43:04

标签: c++ c linux unix

我正在用C编写客户端 - 服务器程序。它发送一个目录名并接收一个文件列表作为答案。我遇到的问题是它陷入无限循环。

如果我只发送一个目录名称,它会起作用,但是如果我发送一个目录列表,它就永远不会结束并且不输出任何内容。

服务器

while(recv(sock, name, BUFSIZE, 0) > 0){
    if ((fddir=opendir(name)) == NULL){
        send(sock, strerror(errno), strlen(strerror(errno)), 0);
        close(sock);
        return 1;
    }
    send(sock, name, strlen(name), 0);
    send(sock, ":", strlen(":"), 0);
    send(sock, "\n", strlen("\n"), 0);
    while ((dirbuf = readdir(fddir)) != NULL){
        buf[0] = '\0';
        strcat(buf, dirbuf->d_name);
        strcat(buf, "\t");
        send(sock, buf, BUFSIZE, 0);
    }
}

客户端

for (int i=1;i<3;i++){
    send(sock, argv[i], strlen(path), 0);
    while(recv(sock, buf, BUFSIZE, 0) > 0)
        printf("%s", buf);
}

服务器等待直到收到所有目录名,然后客户端等到服务器发送其中的所有文件。如何追踪程序卡住的位置?

2 个答案:

答案 0 :(得分:3)

TCP不是基于消息的,因此当您在服务器上调用send()时,无法知道两个客户端recv()调用之间的边界。因此,当您连续发送多个名称时,服务器可以在一个recv()中接收它们(或者为BUFSIZE分配的字节数)。这可能会破坏您的目录名称,导致opendir失败。如果您检查来自sendrecv的错误并且Obvlious船长在另一个答案中描述错误,那么这将更加明显。

答案 1 :(得分:2)

您需要检查对recv的调用是否有错误。如果连接断开,则返回0,出错时返回-1。您只检查不起作用的值> 0。下面的示例显示了如何检查错误。

while(true)
{
    const int result = recv(sock, buf, BUFSIZE, 0);l
    if(result == -1)
    {
        std::cout << "Error: " << errno << std::endl;
        break;
    }

    else if(result == 0)
    {
        std::cout << "Disconnected" << std::endl;
        break;
    }

    //  process the data here. No errors
}

您还应该检查send返回的值,因为它的工作方式相同。