2

A 正在用 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);
}

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

4

2 回答 2

3

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

于 2013-04-27T21:09:56.943 回答
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因为它以相同的方式工作。

于 2013-04-27T20:48:00.630 回答