2015-10-21 20 views
0

我尋找一個非常相似的主題的答案,但我還沒有找到一個好的答案(我認爲)。C選擇總是檢測到套接字可讀

首先我的代碼:

fd_set readset; 
int result; 

while(1) { 
    FD_ZERO(&readset); 
    FD_SET(sock_client, &readset); 
    FD_SET(fileno(stdin), &readset); 
    result = select(sock_client + 1, &readset, NULL, NULL, NULL); 

    if (result > 0) { 
     if (FD_ISSET(sock_client, &readset)) { 
      memset(buffer, 0, sizeof(buffer)); 
      read(server_socket, buffer, 5000); 
      printf("%s", buffer); 
     } 

     if (FD_ISSET(fileno(stdin), &readset)) { 
      memset(msg, 0, sizeof(msg)); 
      read(fileno(stdin), msg, 5000); 
      printf("%s", msg); 
     } 
    } 
} 

EDIT(以()修正後的讀取錯誤):

// socket client 
sock_client = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

// socket server 
server_socket = do_socket(AF_INET, SOCK_STREAM, 0); 

// server connexion 
do_connect(server_socket, 
    (struct sockaddr *) & addr_sock_host, sizeof(addr_sock_host)); 

fd_set readset; 
int result; 

while(1) { 
    FD_ZERO(&readset); 
    FD_SET(sock_client, &readset); 
    FD_SET(fileno(stdin), &readset); 
    result = select(sock_client + 1, &readset, NULL, NULL, NULL); 

    if (result > 0) { 
     if (FD_ISSET(sock_client, &readset)) { 
      memset(buffer, 0, sizeof(buffer)); 
      int size = read(sock_client, buffer, 5000); 
      printf("size : %i\n", size); 
     } 

     if (FD_ISSET(fileno(stdin), &readset)) { 
      memset(msg, 0, sizeof(msg)); 
      read(fileno(stdin), msg, 5000); 
      printf("%s", msg); 
     } 
    } 
} 

當我運行它:

size : -1 
size : -1 
size : -1 
size : -1 
size : -1 
size : -1 
size : -1 
size : -1 

...無限地

END編輯

其實,選擇回報率始終爲1,因爲sock_client總是在讀集,而沒有什麼可閱讀它。更多的是,我的FD_SET處於無限循環中。這就是爲什麼我不明白如何將sock_client檢測爲可讀(始終)?

我希望你能理解我的問題,我很抱歉如果問題已被問到。

感謝

+1

當select指出sock_client可讀時,讀取它時會發生什麼?具體來說,read()調用返回什麼? – Kenster

+1

當您到達EOF時,套接字始終可讀,並且在您讀取時返回「0」。您需要關閉套接字然後停止選擇它。 – Barmar

+0

Select()可讀實際上意味着:「一個read()不會阻塞」(在大多數情況下,等等)並且:在select()可讀之後,您應該執行read()並使用其返回值。 – wildplasser

回答

2

你不需要memset(),,你無法說服我,從監聽套接字塊讀取。這裏真正的問題是,你是:

  • 從錯誤的插座FD讀,
  • 完全無視read()返回的值。

您需要:

  1. 儲存於一個值。
  2. 將它與-1進行比較,如果是,立即撥打perror()或其一個朋友,然後關閉套接字。
  3. 否則,將它比較爲零,如果是,則關閉套接字。
  4. 否則,請使用必須保留的正值作爲傳入數據的長度?這就是爲什麼你不需要memset()