2017-01-23 71 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

相關問題