成功连接2-3次后,客户端停止连接到服务器。c语言中的socket编程

成功连接2-3次后,客户端停止连接到服务器。c语言中的socket编程,c,linux,sockets,C,Linux,Sockets,我正在尝试使用c语言中的套接字编程实现简单的客户机-服务器程序。当我先执行服务器,然后执行客户机时,程序运行良好,但在成功执行两到三次后,客户机停止连接到服务器。如果我在一段时间后执行这些程序,这将再次开始工作 客户端代码: #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h>

我正在尝试使用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;
}
在另一个终端上同时执行服务器:

[kj@localhost 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);
  ^
[kj@localhost Downloads]$ ./server 
Listening
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ 

使用
SO\u REUSEADDR
隐藏了另一个问题:

您的服务器只能为一个客户端提供服务,并且在为一个客户端提供服务时不会完全关闭其侦听套接字

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

在您的代码中,我添加了:

  • 一个
    ,而在第一次客户端连接后,
    循环不停止
  • 一次测试/
    在出现错误时停止服务器
  • 监听插座上的一个
    关闭
    ,以便干净地退出
代码如下:

/* 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;
}
/*包括*/
int main(){
/*初始化*/
if(监听(defSock,5)==0)
printf(“监听”);
其他的
printf(“错误\n”);
len=尺寸(cadd);
//虽然他们没有错
而(1)
{
//等待新连接
newSock=accept(defSock,(struct sockaddr*)和cadd,&len);
//测试客户端连接是否成功
如果(-1==newstock)
{
//出了点问题:杀死服务器
perror(“接受()”);
打破
}
其他的
{
//打招呼
静态常量字符hello[]=“hello,world!\n”;
int n=write(newSock,hello,sizeof hello-1);/*-1以排除最后的“\0”字符*/
if(n<0)
佩罗(“书面”);
关闭(新闻组);
}
}
//然后关闭服务器侦听套接字
关闭(脱套);
返回0;
}

这些警告意味着您缺少一些
#include
行。首先修复此问题。您可以尝试通过
setsockopt()
打开
defSock
上的
SO\u REUSEADDR
套接字选项。您还可以考虑使用服务器循环,以便通过相同的侦听套接字(串行地)服务多个连接。@ JohnBollinger,非常感谢!添加
setsockopt(defSock,SOL_SOCKET,SO_REUSEADDR,&(int){1},sizeof(int))bind(2)
accept(2)
系统调用的返回值。您的服务器可能会失败其中一些调用。通常的做法是检查所有可能失败的系统调用的返回值。
[kj@localhost 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);
  ^
[kj@localhost Downloads]$ ./server 
Listening
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ 
/* 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;
}