2016-02-29 137 views
0

我只是想知道爲什麼當客戶端連接崩潰?它應該是一個簡單的TCP服務器,當客戶端連接併發送一個字符串時,服務器響應字符串中A的個數。服務器一旦崩潰的客戶端類型的一封信TCP服務器崩潰

#include<io.h> 
#include<stdio.h> 
#include<winsock2.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

int main(int argc , char *argv[]) 
{ 
WSADATA wsa; 
SOCKET s , new_socket, master; 
struct sockaddr_in server , address; 
int c, valread; 
char *message = "Welcome to Marshall's TCP Server!!"; 
int MAXRECV = 1024; 
char *buffer; 
char AmmtA = 'a'; 
char AmmtB = 'A'; 
int count = 0, x; 
fd_set readfds; 
buffer = (char*) malloc((MAXRECV + 1) * sizeof(char)); 

printf("\nInitialising Winsock..."); 
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
{ 
    printf("Failed. Error Code : %d",WSAGetLastError()); 
    return 1; 
} 

printf("Initialised.\n"); 

//Create a socket 
if((s = socket(AF_INET , SOCK_STREAM , 0)) == INVALID_SOCKET) 
{ 
    printf("Could not create socket : %d" , WSAGetLastError()); 
} 

printf("Socket created.\n"); 

//Prepare the sockaddr_in structure 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = INADDR_ANY; 
server.sin_port = htons(9000); 

//Bind 
if(bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) 
{ 
    printf("Bind failed with error code : %d" , WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 

puts("Bind done"); 

//Listen to incoming connections 
listen(s , 3); 
//Accept and incoming connection 
puts("Waiting for incoming connections..."); 

c = sizeof(struct sockaddr_in); 

while((new_socket = accept(s , (struct sockaddr *)&address, &c)) != INVALID_SOCKET) 
{ 
    puts("Connection accepted"); 

send(new_socket , message , strlen(message) , 0); 

valread = recv(new_socket , buffer, MAXRECV, 0); 

      if(valread == SOCKET_ERROR) 
      { 
       int error_code = WSAGetLastError(); 
       if(error_code == WSAECONNRESET) 
       { 
        //Somebody disconnected , get his details and print 
        printf("Host disconnected unexpectedly , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); 

        //Close the socket and mark as 0 in list for reuse 
        closesocket(s); 
       } 
       else 
       { 
        printf("recv failed with error code : %d" , error_code); 
       } 
      } 
      if (valread == 0) 
      { 
       //Somebody disconnected , get his details and print 
       printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); 

       //Close the socket and mark as 0 in list for reuse 
       closesocket(s); 
      } 

      else 
      { 
     for (x = 0; buffer[x] != '\0'; x++) { 
       if (buffer[x] == AmmtA || buffer[x] == AmmtB) 
       count++; 
    } 

     char feedback[150]; 
     sprintf(feedback, "There is %d A's in your string", count); 
       feedback[MAXRECV] = '\0'; 
       printf("%s:%d - %s \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port), buffer); 
       send(s , feedback , MAXRECV , 0); 
      } 
free(buffer); 
} 

if (new_socket == INVALID_SOCKET) 
{ 
    printf("accept failed with error code : %d" , WSAGetLastError()); 
    return 1; 
} 

closesocket(s); 
WSACleanup(); 

return 0; 

}

+0

你認爲查找Winsock錯誤代碼10057? – EJP

回答

2

10057 - WSAENOTCONN - 套接字未連接。

發送呼叫是正確的,它使用new_socket。但是recv調用使用socket/sd「s」。 recv調用也應該使用new_socket。

返回錯誤10057,因爲s只綁定到本地端點而不連接到遠端,而accept返回的新套接連接到遠端。

+0

謝謝你這個工作!不幸的是,現在只要客戶端在服務器崩潰時輸入了一些內容。 – MileJet

+0

我建議在每個階段添加錯誤檢查,即在每個API /系統調用之後儘可能早地捕獲錯誤。 –

+0

這是什麼意思?我對C相對比較陌生。 – MileJet

2
for (x = 0; buffer[x] != '\0'; x++) { 
      if (buffer[x] == AmmtA || buffer[x] == AmmtB) 
      count++; 
} 

你爲什麼比較buffer[x] 0有沒有特殊原因在緩衝區內的任何特定條目應該是零,這樣就可以很容易讀出緩衝區的結束。也許你認爲buffer包含一個字符串。但事實並非如此。它包含您從套接字讀取的任何內容,並且沒有特殊的格式或終結符。

幸運的是,您確實知道您讀取的字節數。你存儲在valread,所以你想:

for (x = 0; x < valread; x++) {