我有一个最终想要制作成井字游戏客户端-服务器游戏的程序,但是我目前正在测试发送和打印消息的通信。我可以接受服务器从多个客户端接收消息的点,但是当我尝试强制它在客户端之间交替时,整个事情都会失败,例如从客户端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);
}
}
运行程序时得到的是:在连接第二个客户端时,出现了一个无限循环,其中:
从套接字读取错误:错误的文件描述符
重复多次,然后:
派生错误:资源暂时无法使用
出现两次,最后:
不断重复从套接字读取错误:输入/输出错误
,直到我强制终止程序。 如果我省略了任何必要的信息,请告诉我,我将添加它。谢谢。
答案 0 :(得分:0)
while (1) {
pid = fork();
....
i++;
}
创建太多子进程,最终导致派生失败。
每个孩子使用clientsockfd[i]
;实际上只分配了其中两个。同时i
向无限远发展;第三个进程已经获得了一个垃圾套接字(它也是一个越界访问,因此也是UB),它解释了IO错误。
考虑一次将客户端分叉,并且
while (1) {
doprocessing(clientsockfd[0]);
doprocessing(clientsockfd[1]);
}
在主线上。