2016-10-27 36 views
1

寫爲TCP/IP客戶端 - 服務器的一部分:write()系統調用是否會阻止進一步操作,直到涉及read(),反之亦然?

服務器:

write(nfds,data1,sizeof(data1)); 
usleep(1000); 
write(nfds,data2,sizeof(data2)); 

客戶:

read(fds,s,sizeof(s)); 
printf("%s",s); 
read(fds,s,sizeof(s)); 
printf("%s",s); 

沒有兩個電話之間usleep(1000)write(),客戶端打印數據1次。爲什麼是這樣?

背景:

我做所在服務器都有自己的收購後,發送兩個連續的信息客戶端 - 服務器程序,通過網絡(插座); nfds是我們從accept()獲得的文件描述符。 在客戶端,我們通過read收到這些信息;這裏fds是通過socket()獲得的文件描述符。

我的問題是,當我不使用的write()功能之間的usleep(1000),客戶端只是打印而不是打印數據1,然後通過DATA2 DATA1代表兩次信息。當我輸入usleep()時沒問題。這究竟是爲什麼發生的?是否write()阻止操作直到緩衝區被讀取或者是read()阻止操作直到信息被寫入緩衝區?或者我完全離開了網頁?

+2

您沒有給出足夠的上下文以獲得有意義的答案。 –

+0

你需要什麼?我可以提供它。 –

+3

始終檢查讀取和寫入的返回代碼,以查看它們傳輸了多少個字符。 – meuh

回答

0

你正在做出一些錯誤的假設。 TCP中沒有任何內容保證一次發送等於一次接收。在兩端都有很多緩衝,並且在發送到合併數據包(Nagle算法)時有故意的延遲。當你調用read(),或recv()和朋友,你需要將結果存儲到一個變量並檢查它爲每個以下情況:

  • -1:錯誤:檢查/日誌/打印errno,或strerror() ,或致電perror(),並且在大多數情況下關閉插座並退出讀取循環。
  • 0:流結束;業主已關閉連接;關閉插座並退出讀取循環。
  • 是一個正值,但低於您的預期:請繼續閱讀並累積數據,直到您擁有所需的一切爲止。
  • 一個正值,超出您的預期:處理您預期的數據,並在下次保存其餘數據。
  • 與您的預期完全相同:處理數據,丟棄所有數據,然後重複。這不是一件容易的事情,也很少見,但它是您目前編程的唯一案例。

不要在網絡代碼中加入睡眠。它不能解決問題,它只會拖延它們。

+0

我已經使用基於條件的檢查read()和寫(),aong與perror()。 使用usleep()解決了代碼所具有的問題。你可以說一旦usleep()被添加後,爲什麼「data1」被讀取兩次,然後是「data1」和「data2」(根據需要)? –

相關問題