gpt4 book ai didi

客户端在 2-3 次成功连接后停止与服务器的连接。 c 中的套接字编程

转载 作者:行者123 更新时间:2023-11-30 19:11:11 25 4
gpt4 key购买 nike

我正在尝试使用 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;
}

在终端中多次执行客户端:

[kj@localhost 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));
^
[kj@localhost Downloads]$ ./client
Data received: Hello World
[kj@localhost Downloads]$ ./client
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$ ./client
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$ ./client
trying again..
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$

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

[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_REUSEADDR隐藏了另一个问题:

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

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

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

  • 一个 while 循环在第一个客户端连接后不停止,
  • 一次测试/perror,用于在出现错误时停止服务器,
  • 对监听套接字进行一次关闭以干净退出。

这是代码:

/* 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;
}

关于客户端在 2-3 次成功连接后停止与服务器的连接。 c 中的套接字编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40517238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com