我有一个程序,最终我想把它做成一个井字游戏客户端 - 服务器游戏,但我目前只是在测试与发送和打印消息的通信。在服务器接收来自多个客户端的消息之前,我没问题,但是当我尝试强制它在客户端之间交替时,整个事情都失败了,例如从客户端 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);
}
}
我在运行程序时得到的是:在连接第二个客户端时,有一个无限循环,其中:
从套接字读取错误:文件描述符错误
重复多次,然后:
叉上的错误:资源暂时不可用
出现两次,最后:
从套接字读取错误:输入/输出错误
无休止地重复,直到我强制终止程序。如果我遗漏了任何必要的信息,请告诉我,我会添加它。谢谢。
while (1) {
pid = fork();
....
i++;
}
创建过多的子进程,最终导致fork失败。
每个孩子都使用clientsockfd[i]
; 其中只有两个被实际分配。同时i
向无穷大增长;第三个进程已经获得了一个垃圾套接字(它也是一个越界访问,因此是UB),这解释了IO错误。
考虑将客户端分叉一次,然后
while (1) {
doprocessing(clientsockfd[0]);
doprocessing(clientsockfd[1]);
}
在主线。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句