1

我正在编写一个小而简单的服务器(用于 Linux 站的 C 语言)。

客户端向我的服务器请求文件,我的服务器将此文件请求给另一台服务器,另一台服务器将其发送到我的服务器。

我的服务器在将文件发送到客户端之前不应接收所有文件,但必须在文件到达时发送文件的字节。

这是学校的练习,所以我不能脱离这个要求。

我已经实现了下面解释的功能。问题是客户端接收到不确定的字节数并且从不接收整个文件。

int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){

    size_t n;

    ssize_t nread;

    ssize_t nwritten;

    char c;

    for (n=1; n<file_size; n++)
    {        
            nread=recv(socketa, &c, 1, 0);

            if (nread == 1)
            {
                nwritten = send(socketb,&c,1,0);
            }
            else if (nread == 0)
            {
                *buffer = 0;
                return (-1); /* Errore */
            }
            else
                return (-1); /* Errore */
            }
    }
    *buffer = 0;
    return (n); 
}

有人可以告诉我我哪里错了吗?

在服务端和客户端同时改变 SO_SNDBUF 和 SO_RCVBUF 的值是不是很傻?

4

3 回答 3

1

假设file_size是您要发送的字节总数,那么您的for循环将只发送file_size - 1字节。换句话说,你差了一个。从0改为解决此问题:

    for (n=0; n<file_size; n++)
    { //..

您捕获 的返回值send(),但不检查它是否成功。

您将相同的0返回值recv()视为错误。由于您在从函数返回后没有显示您所做的事情-1,我不知道这是否会导致您的问题。

某些错误是“软”的send()recv()因为您可以针对这些特定错误重试操作。此类错误之一是EINTR,但请检查系统上的文档以查看是否有其他错误。

于 2013-06-25T20:20:11.533 回答
1

为了优化性能和简化代码,可以使用 splice()+pipes。Sendfile 使您能够在文件描述符之间“转发”数据,而无需复制到用户空间。

于 2013-06-25T20:25:39.570 回答
1

你确定你复制了正确的代码吗?该部分无法编译,最后一个 else 中有一个 } 与相应的 { 不匹配。

另外,您如何知道文件大小?如果它作为整数通过套接字发送,请记住源机器和目标机器的可能字节顺序。

无论如何,您一次读取一个字节,您应该这样改进它:

编辑:使用缓冲区而不是额外的 buff[2048];

int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){

    ssize_t nread;
    ssize_t nwritten;
    ssize_t bLeft=file_size;

    while (bLeft > 0)
    {
        nread=recv(socketa, buffer, bleft, 0);
        if (nread > 0)
        {
            nwritten = send(socketb, buffer, nread, 0);
            bLeft -= nread;
            buffer+=nread;
        }
        else if (nread == 0)
        {
            // I think this could raise a memory exception, read below
            *buffer = 0;
            return (-1); /* Errore */
        }
        else
        {
            return (-1); /* Errore */
        }
    }
    // If buffer is allocated with file_size bytes this one will raise a memory exception
    // *buffer = 0;
    return (file_size-bLeft);
}
于 2013-06-25T20:27:05.063 回答