簡體   English   中英

select()始終返回0

[英]select() always returns 0

我似乎有select的問題。

while(!sendqueue.empty())
{                                   
  if(!atms_connection.connected)
  {
    //print error message
    goto RECONNECT;
  }

  //select new
  FD_ZERO(&wfds);
  FD_SET(atms_connection.socket, &wfds);

  tv.tv_sec = 1;
  tv.tv_usec = 0;

  retval = select(atms_connection.socket + 1, NULL, &wfds, NULL, &tv);

  if (retval == -1) {
    printf("Select failed\n");                      
    break;
  }                     
  else if (retval) {
    printf("Sent a Message.\n"); 
  }
  else {
    //printf("retval value is %d\n",retval);
    printf("Server buffer is full, try again...\n");                        
    break;
  }
  n = write(atms_connection.socket, sendqueue.front().c_str(), sendqueue.front().length());
}

該函數屬於一個線程,當它獲取鎖時,使用select()清除隊列並在循環中寫入套接字直到隊列為空。

第一次線程獲得鎖定時, select()很好,但是第二次獲取鎖定並進入while時它總是返回0。

為了記錄,它曾經很好地工作了一段時間,從那以后我沒有改變那些代碼。

超時時選擇返回0。 以下行指定超時為1秒。

tv.tv_sec = 1;

通常,套接字已准備好進行寫入,而select將立即返回。 但是,如果套接字輸出緩沖區中沒有空間用於新數據,則select不會將此套接字標記為准備寫入。

例如,當連接的另一端未調用recv/read時,可能會發生這種情況。 未確認數據的數量增加,緩沖區最終變滿。 由於超時相當小,因此select經常返回值為0。

除了已經提到的內容之外,選擇api本身只會告訴描述符是否准備就緒。 它可以用於讀取或寫入,具體取決於所選擇的操作。

在您的情況下,“發送的消息”打印似乎給出了實際寫入數據的錯覺,但事實並非如此。 您必須對描述符進行寫入調用,該描述符將從select返回為ready。

Select不會神奇地讀取或寫入緩沖區。 如果您是偵聽服務器,則在選擇調用成功返回后調用accept或read。 如果您是客戶端並且打算編寫(就像在您的情況下出現的那樣),您需要進行顯式的write()或send()調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM