C TCP/IP 套接字:如何同步从客户端套接字到服务器套接字的输入是交替的
C TCP/IP Sockets: How to synchronise input from client sockets to a server socket to be alternating
我有一个程序,最终我想制作成井字棋客户端-服务器游戏,但我目前只是测试发送和打印消息的通信。在服务器从多个客户端接收消息之前我还好,但是当我试图强制它在客户端之间交替时,整个事情都失败了,比如从客户端 1、然后是客户端 2、然后是 1 等获取输入。我我确信我只是在以一种非常错误的方式去做这件事。
这是建立连接并与客户端通信的代码。
listen(sockfd,5);
clilen = sizeof(cli_addr);
//client1
clientsockfd[0] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (clientsockfd[0] < 0) {
perror("ERROR on accept");
exit(1);
}
//client2
clientsockfd[1] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (clientsockfd[1] < 0) {
perror("ERROR on accept");
exit(1);
}
while (1) {
//create child process for each client
pid1 = fork();
if (pid1 < 0) {
perror("ERROR on fork");
exit(1);
}
//client1
if (pid1 == 0) {
/* This is the client process */
close(sockfd);
doprocessing(clientsockfd[i]);
}
//client2
if(pid2 == 0){
close(sockfd);
doprocessing(clientsockfd[i]);
//functions
}
i++;
}
我也尝试在第一次分叉中进行第二次分叉,但也失败了。
这里是client.c关于与服务器通信的部分。
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Error connecting: ");
exit(1);
}
while(1){
//ask for message to be read by server
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
// send message
n = write(sockfd, buffer, strlen(buffer));
if (n < 0) {
perror("Error writing to socket: ");
exit(1);
}
//empty buffer
bzero(buffer,256);
//read reply from server
n = read(sockfd, buffer, 255);
if (n < 0) {
perror("Error reading from socket: ");
exit(1);
}
printf("%s\n",buffer);
}
return 0;
}
这里还有 doprocessing 功能,以备不时之需
void doprocessing (int sock) {
int n;
char buffer[256];
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
n = write(sock,"I got your message",18);
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
当运行程序时我得到的是:在第二个客户端连接时,有一个无限循环,其中:
ERROR reading from socket: Bad file descriptor
重复多次,则:
ERROR on fork: recourse temporarily unavailable
出现了两次,最后:
ERROR reading from socket:Input/output error
不断重复,直到我强制终止程序。
如果我遗漏了任何必要的信息,请告诉我,我会添加它。谢谢。
while (1) {
pid = fork();
....
i++;
}
创建了太多 child 个进程,最终导致分叉失败。
每个child使用clientsockfd[i]
;实际上只有两个被分配。同时 i
向无穷大增长;第三个进程已经得到一个垃圾套接字(它也是一个 out-of-bound 访问,因此是 UB),这解释了 IO 错误。
考虑改为分叉客户端一次,并且
while (1) {
doprocessing(clientsockfd[0]);
doprocessing(clientsockfd[1]);
}
在主线中。
我有一个程序,最终我想制作成井字棋客户端-服务器游戏,但我目前只是测试发送和打印消息的通信。在服务器从多个客户端接收消息之前我还好,但是当我试图强制它在客户端之间交替时,整个事情都失败了,比如从客户端 1、然后是客户端 2、然后是 1 等获取输入。我我确信我只是在以一种非常错误的方式去做这件事。
这是建立连接并与客户端通信的代码。
listen(sockfd,5);
clilen = sizeof(cli_addr);
//client1
clientsockfd[0] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (clientsockfd[0] < 0) {
perror("ERROR on accept");
exit(1);
}
//client2
clientsockfd[1] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (clientsockfd[1] < 0) {
perror("ERROR on accept");
exit(1);
}
while (1) {
//create child process for each client
pid1 = fork();
if (pid1 < 0) {
perror("ERROR on fork");
exit(1);
}
//client1
if (pid1 == 0) {
/* This is the client process */
close(sockfd);
doprocessing(clientsockfd[i]);
}
//client2
if(pid2 == 0){
close(sockfd);
doprocessing(clientsockfd[i]);
//functions
}
i++;
}
我也尝试在第一次分叉中进行第二次分叉,但也失败了。
这里是client.c关于与服务器通信的部分。
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Error connecting: ");
exit(1);
}
while(1){
//ask for message to be read by server
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
// send message
n = write(sockfd, buffer, strlen(buffer));
if (n < 0) {
perror("Error writing to socket: ");
exit(1);
}
//empty buffer
bzero(buffer,256);
//read reply from server
n = read(sockfd, buffer, 255);
if (n < 0) {
perror("Error reading from socket: ");
exit(1);
}
printf("%s\n",buffer);
}
return 0;
}
这里还有 doprocessing 功能,以备不时之需
void doprocessing (int sock) {
int n;
char buffer[256];
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
n = write(sock,"I got your message",18);
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
}
当运行程序时我得到的是:在第二个客户端连接时,有一个无限循环,其中:
ERROR reading from socket: Bad file descriptor
重复多次,则:
ERROR on fork: recourse temporarily unavailable
出现了两次,最后:
ERROR reading from socket:Input/output error
不断重复,直到我强制终止程序。 如果我遗漏了任何必要的信息,请告诉我,我会添加它。谢谢。
while (1) {
pid = fork();
....
i++;
}
创建了太多 child 个进程,最终导致分叉失败。
每个child使用clientsockfd[i]
;实际上只有两个被分配。同时 i
向无穷大增长;第三个进程已经得到一个垃圾套接字(它也是一个 out-of-bound 访问,因此是 UB),这解释了 IO 错误。
考虑改为分叉客户端一次,并且
while (1) {
doprocessing(clientsockfd[0]);
doprocessing(clientsockfd[1]);
}
在主线中。