2016-11-09 55 views
-1

我正在尝试使用套接字编程在c中简单的客户端服务器程序。当我首先执行服务器然后执行客户端时,程序工作正常,但在两到三次成功执行后,客户端停止连接到服务器。如果我在一段时间后执行程序,这又开始工作。客户端在2-3次成功连接后停止连接到服务器。 socket编程在c

客户机代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 

int main(){ 
    int clientSocket,len; 
    char buffer[1024]; 
    struct sockaddr_in sadd; 

    clientSocket = socket(PF_INET, SOCK_STREAM, 0); 

    sadd.sin_family = AF_INET; 
    sadd.sin_port = htons(12345); 
    sadd.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    memset(sadd.sin_zero, '\0', sizeof sadd.sin_zero); 

    len = sizeof sadd; 
    while(connect(clientSocket, (struct sockaddr *) &sadd, len) == -1) { 
     sleep(1); 
     printf("trying again..\n"); 
    } 

    read(clientSocket, buffer, sizeof(buffer)); 
    printf("Data received: %s",buffer); 

    return 0; 
} 

服务器代码:

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 

int main(){ 
    int defSock, newSock, len; 
    char buffer[1024]; 
    struct sockaddr_in sadd, cadd; 


    socklen_t addr_size; 

    defSock = socket(PF_INET, SOCK_STREAM, 0); 

    sadd.sin_family = AF_INET; 
    sadd.sin_port = htons(12345); 
    sadd.sin_addr.s_addr = INADDR_ANY; 

    bind(defSock, (struct sockaddr *) &sadd, sizeof(sadd)); 

    if(listen(defSock,5)==0) 
     printf("Listening\n"); 
    else 
     printf("Error\n"); 

    len = sizeof(cadd); 

    newSock = accept(defSock, (struct sockaddr *) &cadd, &len); 
    strcpy(buffer,"Hello World\n"); 
    int n = write(newSock,buffer,sizeof(buffer)); 

    close(newSock); 

    return 0; 
} 

在终端多次执行客户端:

[[email protected] Downloads]$ gcc client.c -o client 
client.c: In function ‘main’: 
client.c:16:25: warning: implicit declaration of function ‘inet_addr’ [-Wimplicit-function-declaration] 
    sadd.sin_addr.s_addr = inet_addr("127.0.0.1"); 
         ^
client.c:21:3: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration] 
    sleep(1); 
^
client.c:25:2: warning: implicit declaration of function ‘read’ [-Wimplicit-function-declaration] 
    read(clientSocket, buffer, sizeof(buffer)); 
^
[[email protected] Downloads]$ ./client 
Data received: Hello World 
[[email protected] Downloads]$ ./client 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
^C 
[[email protected] Downloads]$ ./client 
trying again.. 
trying again.. 
trying again.. 
^C 
[[email protected] Downloads]$ ./client 
trying again.. 
trying again.. 
trying again.. 
trying again.. 
^C 
[[email protected] Downloads]$ 

另一终端上同时执行的服务器:

[[email protected] Downloads]$ gcc server.c -o server 
server.c: In function ‘main’: 
server.c:31:10: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration] 
    int n = write(newSock,buffer,sizeof(buffer)); 
     ^
server.c:33:2: warning: implicit declaration of function ‘close’ [-Wimplicit-function-declaration] 
    close(newSock); 
^
[[email protected] Downloads]$ ./server 
Listening 
[[email protected] Downloads]$ ./server 
Listening 
^C 
[[email protected] Downloads]$ ./server 
Listening 
^C 
[[email protected] Downloads]$ ./server 
Listening 
^C 
[[email protected] Downloads]$ 
+3

这些警告的意思是你错过了一些'#include'线。首先解决它。 – Barmar

+1

你可以尝试通过'setsockopt()'在'defSock'上打开'SO_REUSEADDR'套接字选项。你也可以考虑让服务器循环,以便通过同一个监听套接字(串行)为多个连接提供服务。 –

+0

@JohnBollinger,非常感谢!添加'setsockopt(defSock,SOL_SOCKET,SO_REUSEADDR,&(int){1},sizeof(int));'使代码生效。 –

回答

1

采用SO_REUSEADDR隐藏了另一个问题:

你的服务器只能够服务一个客户端,并且不干净关闭其监听套接字,当一个客户端已送达。

要解决此问题,您应该在服务器中添加一个while循环以允许多个客户端连接。

在代码中,我说:

  • 一个while循环不停止第一客户端连接后,
  • 一个测试/ perror停止服务器在出现错误时,
  • 一个close在听取插座清洁出口。

这是代码:

/* include */ 

int main(){ 

    /* init */ 

    if(listen(defSock,5)==0) 
     printf("Listening\n"); 
    else 
     printf("Error\n"); 

    len = sizeof(cadd); 

    // while they're no error 
    while (1) 
    { 
     // wait for new connection 
     newSock = accept(defSock, (struct sockaddr *) &cadd, &len); 

     // test if client connection succeded 
     if (-1 == newSock) 
     { 
      // something went wrong: kill the server 
      perror("accept()"); 
      break 
     } 
     else   
     { 
      // say hello 
      static const char hello[] = "Hello, world!\n"; 
      int n = write(newSock, hello, sizeof hello - 1); /* -1 to exclude the final '\0' char */ 
      if (n < 0) 
       perror("write"); 
      close(newSock); 
     } 
    } 

    // And close the server listening socket 
    close(defSock); 

    return 0; 
}