即使套接字为空,C recv()仍继续读取

时间:2015-09-27 03:28:57

标签: c sockets

新的套接字编程。我正在制作一个HTTP服务器。在持久连接中,我在服务器从客户端发送第一个HTTP请求的第一个文件(1 MB文本文件)后保持套接字打开。之后,服务器和客户端程序就处于空闲状态。我搜索了很多,发现recv()一直在寻找套接字上的数据,直到套接字连接从服务器端关闭。

如果持续连接,我该怎么办? 我正在客户端读取一个文件(文件包含很多行。在每一行上只有一个文件名,即通过持久连接从服务器获取)

发送请求文件的服务器代码的一部分:

while((bytesread = fread(filecontent,sizeof(char), 1024, fp))>0)
{
    printf("Bytes Read:%d File Content:%s\n",bytesread,filecontent);
    if((n = send(*newsockfd, filecontent, 1024,0))<0)
    {
        error("SERVER Error: Failed to Write File to Socket");
        break;
    }
    bzero(filecontent,1024);
}

我读取服务器发送的文件的部分客户端代码:

for(;;)
{
    n=recv(socketfd, buffer, 1024,0);
    printf("%d\n",n);
    if(n>0)
    {       printf("\n in while for reading the file for n bytes %d \n",n);
            printf("Response:\n%s",buffer);
    }
    else if(n<0)
    {
            disperror("Error reading from socket");
    }
    if(n==0)
            break;
}

花了很多时间。无法做什么......

2 个答案:

答案 0 :(得分:0)

您的客户端 - 服务器协议不足。服务器发送输入文件的所有字节(以及更多,因为您使用硬编码1024而不是使用bytesread)。但客户应该如何理解文件何时完成?

一个简单的解决方案是让服务器以文件大小开始每次传输。您只需发送uint64_t(不是int,因为它必须是所有平台上的固定大小)。该数字将表示要遵循的总字节数(即文件大小)。您可以按常规方式fseek然后SEEK_END或类似方式使用ftell获取文件大小。

然后,一旦您的客户端收到指定的字节数,它就可以突破循环。

答案 1 :(得分:0)

  即使套接字为空,

继续读取

'Socket is empty'毫无意义。它是开放的还是封闭的。在这种情况下,它仍处于打开状态,因此您的代码会继续读取。它只会在对等方关闭连接时停止。

如果您要实施HTTP,则需要具备RFC 2616的良好工作知识,尤其是与内容长度相关的部分。你的代码目前还没有开始解决这个问题,而且这个问题太过于深奥。可以说,keepalive和读取套接字到流的末尾是相互矛盾的。

注意如果读取EAGAIN/EWOULDBLOCK以外的套接字时出错,则应该退出循环,并且还应该打印真实的错误,而不是您自己设计的一些消息。

注意(2)您不需要将缓冲区归零。

注意(3)打印缓冲区的正确方法是printf("%.*s", n, buffer),但仅限于n > 0