2016-02-13 83 views
0

我有一個連接到某個服務器的應用程序。它可以同步發送數據(發送和等待應答)和異步接收數據。 我做了2個線程。在無限循環的第一個線程中,我發送數據並等待答案。在第二個線程中,我正在從服務器獲取數據,並將它們推送到隊列中。 但是,如果我發送數據時發生了一些錯誤(在第一個線程中),我必須關閉套接字。我該如何檢查第二個線程是否關閉了套接字?檢查插座關閉

代碼在第二個線程:

while (processing) { 
    nbytes = recv(socketDesc, canFrame, sizeof(data), 0); 
    if (nbytes > 0) { 
    push_queue(data); 
    } 
    if (nbytes < 0) { 
    throw "Error in read data from socket!"; 
    } 
} 

如果我關閉套接字在第一個線程在第二個線程功能recv不採取錯誤。現在我用的超時,這樣的:

setsockopt(this->socketDesc, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); 
    setsockopt(this->socketDesc, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)); 

當我不從服務器獲取答案(第一線程)我設置變量processing爲false,超時後(在功能recv)循環是錯誤發生結束。我是否可以在功能recv中同時檢查套接字是否關閉?

+0

你如何關閉套接字?使用close()?你有沒有嘗試過使用shutdown()?shutdown()可以選擇丟棄未決的讀取和/或寫入數據,因此可能有所幫助。 –

回答

1

沒有及時確定您關閉了套接字的方法。您需要一個變量在兩個線程之間共享並由互斥鎖保護。第一個線程可以在關閉套接字時設置變量,第二個線程在執行recv之前應該檢查它。

+0

因此,我必須使用SO_RCVTIMEO和SO_SNDTIMEO設置setsockopt.to來完成recv函數並檢查第二個線程中的共享變量? – Mike

+0

不,在你剛剛關閉套接字時設置共享變量,並在嘗試「recv」之前在另一個線程中檢查它。你不需要超時。 –

+0

嗯。如果在recv中不使用超時,那麼即使套接字關閉,它也將工作在無限狀態。 – Mike

1

下面是如何確保在讀取線程正在讀取時不關閉套接字。

你必須通過一個互斥體保護2個共享布爾變量:

bool reading = false; 
bool closed = false; 

所有訪問這些被鎖定的互斥體之前,通過解鎖它成功。

寫入線程:

  1. 寫入
  2. 如果寫入失敗:
    1. closed
    2. 等待reading成爲false
    3. 關閉套接字

讀線程:

  1. 將檢查closedtrue。如果不是:
    1. readingtrue
    2. 讀取
    3. readingfalse
+0

我是如此可惜,但我仍然不會延期......如果我調用'recv',它會在不獲取數據的情況下工作。即使不向服務器發送請求,數據也會來。我必須永久檢查來自服務器的傳入數據。 – Mike

+0

如果我將在'recv'中使用超時,我可以檢查套接字的狀態,如果它關閉,我完成循環或如果套接字打開,我再次調用'recv'。 – Mike