【问题标题】:Multiple writes in server socket to single read in client socket program?服务器套接字中的多次写入到客户端套接字程序中的一次读取?
【发布时间】:2017-06-07 11:59:59
【问题描述】:

我已经看到很多与我正在尝试做的事情相关的问题,但我还没有找到任何适合我的解决方案。

我正在尝试编写两个套接字程序(一个客户端和一个服务器),以便服务器能够将任何类型的文件(按字节)发送到客户端。我不确定如何构建/协调以下内容:

  1. (在服务器中)从文件中获取数据的读取语句(我正在使用 fread())

  2. (在服务器中)将数据发送到客户端的 write 语句(我正在使用 write())

  3. (在客户端)从服务器接收数据的读取语句(我正在使用 read())

  4. (在客户端)用于将从服务器接收到的数据写入文件的写入语句(我正在使用 fwrite())

我想以字节块的形式传输数据。无论文件有多大,服务器中的一条 fread() 语句和一条 write() 语句是否足够? (或者这取决于我的缓冲区的大小?) 在客户端,一次调用 read() 和一次调用 fwrite() 就足够了吗? (或者这取决于我的缓冲区的大小?)

我是套接字编程的新手。提前致谢! 下面是我的服务器和客户端的一部分:

客户端:

/*try to get file from server*/

  char receive_buffer[256];
    FILE * new_file;

    int bytes_received = 0;

    new_file = fopen("newfile.txt", "w");

    bytes_received = read(conn_s, receive_buffer, 256);

    printf("Received %d bytes\n", bytes_received);

    while( bytes_received > 0)
    {   
        bytes_received = read(conn_s, receive_buffer, 256);
        printf("Received %d bytes\n", bytes_received);
        fwrite(receive_buffer, 1, bytes_received, new_file);
        printf("writing bytes!\n");
        break;
    }
    if(bytes_received < 0)
    {
        printf("/nError reading bytes of data/n");
    }

部分服务器代码:

FILE * file_to_get = fopen("sample.txt", "rb");
    if(file_to_get == NULL)
    {
        printf("No such file!");
        exit(0);
    }
    while(1)
    {
        unsigned char buff[256];
        int num_read = fread(buff, 1, 256, file_to_get);
        printf("read %d bytes\n", num_read);
        if(num_read > 0)
        {
            write(conn_s, buff, num_read);
            printf("writing %d bytes\n", num_read);
        }    

        if(num_read < 256)
        {
            if(feof(file_to_get))
                printf("End of file\n");
            if(ferror(file_to_get))
                printf("Error reading bytes\n");
            break;
        }    
    }

【问题讨论】:

  • 只是一个简短的说明,请务必检查每个系统调用是否失败(即fopen()等(指您的客户端)。
  • 作为一般规则,您应该检查任何返回字节数的系统调用的返回值,并正确处理它返回的任何返回值。这意味着当它返回与您传入的相同字节数时您需要处理它(即缓冲区的完整读/写),并且当它返回的值小于您传入的值时您需要处理它(即你的缓冲区的部分读/写)。最后,您需要在它返回 0(又名文件结尾)和返回 -1(又名错误)时处理它。

标签: c sockets tcp


【解决方案1】:

发送到网络时,您可以使用单个呼叫write()。如果内核中没有足够的缓冲区空间来处理整个事情,write() 将阻塞,直到它能够处理所有事情。你也可以分块写,也可以。没关系。

从网络读取时,必须循环调用read()。您在调用read() 时指定的缓冲区大小只是它允许返回的最大值,它不会等待收到那么多。所以它可以(而且经常确实)回报低于这个值。继续调用read(),直到它返回0 表示EOF,将每个缓冲区写入文件。

【讨论】:

  • 谢谢,所以,(在服务器中)我从文件中读取一次,向网络写入一次?并且(在客户端)我从网络读取并循环写入文件?
  • 是的,这是一个很好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 2016-02-08
  • 2017-10-05
  • 2017-02-25
  • 2014-11-05
相关资源
最近更新 更多