2017-01-23 69 views
0

我见过很多与我正在做的事情有关的问题,但我还没有能够得到任何解决方案为我工作。在服务器套接字中多次写入客户端套接字程序中的单次读取?

我试着写两个套接字程序(一个客户端和一个服务器),以便服务器能够发送任何类型的文件(按字节)到客户端。我不知道如何构建/协调如下:

  1. (服务器)的读取声明(S),从文件中获取数据(我用的fread())

  2. (在服务器端)向客户端发送数据的写入语句(我正在使用write())

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

  4. (在客户端中)写入wr的语句迭代从服务器接收到的数据到文件(我正在使用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; 
     }  
    } 
+0

只是一个简短的提示,一定要检查**每个**系统调用失败(即'fopen()'等)(指您的客户端) – RastaJedi

+1

作为一般规则,您应该检查任何系统调用的返回值都会返回字节数并正确处理它返回的任何返回值,这意味着当它返回相同的字节数时(即完全读/写你的缓冲区),并且当你返回的值小于你传入的值时(比如缓冲区的部分读/写),你需要处理它。最后,当它返回0(也就是说,文件),当它返回-1(又名一个错误)。 –

回答

3

当发送到网络上,你可以用它来write()单个呼叫。如果整个内核中没有足够的缓冲空间,那么write()将会阻塞,直到它能够处理所有内容为止。你也可以把它写成块,这也很好。这并不重要。

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

+0

谢谢,所以,(在服务器中)我从文件中读取一次,并写入一次到网络和(在客户端)我从网络读取和在循环中写入文件? – David

+0

是的,这是一个好方法 去做吧。 – Barmar

相关问题