2009-11-25 101 views
7

在Linux中的套接字編程中我需要在套接字中寫入數據,但我不知道套接字是打開還是關閉。如何知道該套接字是打開並關閉而未讀取的?檢查連接是否打開或關閉?(在Linux中爲C)

printf("befor read%d\n", n); 
bzero(buffer, MAX_SIZE_BUFFER); 
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1); 
printf("after read%d\n", n); 
if (n <= 0) 
{ 
    break; 
} 
printf("befor write%d, s: %d \n", n , sockfd); 

n = write(newsockfd, buffer, n); 
if (n <= 0) 
{ 
    break; 
} 

我從sockfd讀取,我確信這個連接是打開的。何時在newsockfd中寫緩衝區我不知道newsockfd是打開還是關閉如何檢查newsockfd是否已關閉?


我知道問題。在書寫連接中間關閉。例如在500個連接關閉並寫入程序時寫入1024個數據。如何避免這一點?

回答

11

我使用發送()代替寫(),該處理沒有信號:

bzero(buffer, MAX_SIZE_BUFFER); 
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1); 
printf("after read%d\n", n); 
if (n <= 0) 
{ 
    break; 
} 
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL); 
if (n2 == -1) 
{ 
    close(sockfd); 
    close(newsockfd); 
    return; 
} 
if (n2 != n) 
{ 
    break; 
} 
中的下一行
+0

這會起作用,另一種選擇是使用'sigaction'來忽略'SIGPIPE'(將其處理程序設置爲'SIG_IGN')。 – caf 2009-11-25 12:42:56

15

檢查,如果你可以寫一個插座,奇怪的是,嘗試如果已經關閉了套接字寫吧:-)

的樣子,你會從write,你會得到一個-1返回碼可以檢查errno以查看問題所在。

如果套接字仍然有效,但你不能在此刻寫入任何數據,write將返回0。read通話也表現在以類似的方式,返回-1如果有一個問題。

基本上,write

  • ,如果你得到一個-1,還有的是一個問題,你應該檢查errno,看它是否是可回收或可致命。
  • 如果你找回0,那麼你現在不能寫任何東西(可能是網絡積壓或其他問題,但絕對不是(致命的))。
  • 如果您獲得的價值低於您的要求,那麼部分的數據已發送。調整你的指針,這樣你可以嘗試在下一個週期中發送剩下的指針。如果不是假定正返回值表示整個塊已經發送。
  • 如果您返回的數字與您嘗試發送的字節數相同,則整個緩衝區已被接受發送。
  • 如果您回覆的內容超過您要求發送的內容,請發送電子郵件給內核開發人員,並提供一些尖銳的評論。萊納斯等人會喜歡:-)

更新:作爲非洲足聯在評論中指出,我忘了考慮到信號處理。您必須忽略破損的管道信號,否則write將通過提升該信號而在內部失效。

您可以通過插入這樣做:

struct sigaction new_actn, old_actn; 
new_actn.sa_handler = SIG_IGN; 
sigemptyset (&new_actn.sa_mask); 
new_actn.sa_flags = 0; 
sigaction (SIGPIPE, &new_actn, &old_actn); 

開始使用socket函數之前。然後您可以使用:

sigaction (SIGPIPE, &old_actn, NULL); 

恢復以前的信號處理。

+0

看看是否(N <= 0),但在寫功能一些發生錯誤和關閉程序 – SjB 2009-11-25 07:30:22

+0

@SjB,如果'write'返回0,則不* *會產生問題。如果存在臨時網絡積壓,則可能發生這種情況。如果積壓成爲真正的問題,會話將被關閉,您最終會得到-1。在此之前,繼續嘗試。 – paxdiablo 2009-11-25 07:35:51

+0

我知道問題。在書寫連接中間關閉。例如在500個連接中寫入1024個數據並關閉程序 – SjB 2009-11-25 08:10:59

4

套接字編程可能相當棘手,因爲您經常不知道直到很晚才發生錯誤。例如,如果您正在寫入的機器異常關閉,則寫入調用可能成功(因爲您可以寫入內部OS緩衝區),只能在關閉調用期間失敗。

除非您有驗證套接字的應用層方法是活動的(即發送消息並在一段時間內要求響應),否則您無法知道。如果您使用的是標準協議,則可能已經存在處理錯誤的內容。

所以簡短的回答是,你需要檢查幾乎所有接觸套接字(讀,寫,關閉等)的調用返回的錯誤。

+2

不幸的是,這是正確的答案。我嘗試了幾種方法來確定保持活動的HTTP連接是否仍然有效,但它不可靠,沒有競爭條件。 – Lothar 2014-04-22 22:41:07

相關問題