2012-11-07 44 views
1

我正在爲一個項目創建一個遊戲,其中有一個高分服務器,遊戲可以發送命令來保存一個新的高分,獲得前10分,等等。我遇到的問題是,在遊戲向服務器發送了幾個命令並且它們執行得很好之後,即使遊戲沒有發送任何東西,電話read()也只是繼續收到nullC-read()永遠不會在服務器端阻塞

我搜索周圍的解決方案,我查了下,他們都OK:

1-創建任何插座的時候,我檢查if (sockfd==-1)和打印錯誤並退出
2 - 我能阻止每個插座模式明確
3-我測試了所有插座

if(n < 0){ 
    perror("Read Error:"); 
} 

,它永遠不會進入這裏,但我改

if(n == 0){ 
    perror("Read Error:"); 
} 

和我得到壞地址!有關如何讓閱讀功能等待直到遊戲實際執行發送的任何幫助?

這裏是發送和閱讀代碼失敗:

服務器:

listen(sock, 5); 
clientlength = sizeof(client_add); 
newsock = accept(sock, (struct sockaddr *) &client_add, &clientlength); 
if(newsock < 0){ 
    printf("Couldn't accept\n"); 
} 
while(1){ 
    bzero(buffer, 300); 
    ioctl(newsock, FIONBIO, 0); 
    n= read(newsock, buffer, 299); 
    if(n == 0){ 
    perror("Read Error:"); 
    } 
    if(n<0){ 
    printf("Error while reading from socket\n"); 
    } 
    printf("Received: %s\n",buffer); 
    //send to function that processes the string 
    dothemagic(buffer); 
} 

發送的MSG的例子:

strcpy(buffer, "gettop5"); 
n = write(sock,buffer,strlen(buffer)); 
if (n < 0){ 
    printf("Writing to socket was unsuccessful\n"); 
} 
+1

Errno(和perror)僅在失敗的系統功能後有效。讀取返回零不是一個失敗的系統調用,所以errno包含垃圾。另外:檢查EINTR/EAGAIN,然後重試。 – wildplasser

回答

1

最大的問題是,你的printf/PERROR只打印一條消息,但隨後繼續執行(使用歸零緩衝區...);你應該打印一個錯誤,然後從循環中退出/退出程序/任何合適的。就像wildplasser指出的那樣,n == 0不是錯誤。

如果您仍然無法弄清楚,請嘗試short, self contained, correct example - 這很讓人印象深刻,您只需將sscce放在一起就能意識到這個問題!