我最终想制作成井字棋客户端 - 服务器的游戏程序,但我目前只是发送和打印信息测试通信。我好到服务器接收来自多个客户端的消息的点,但整个事情时,我试图迫使其客户之间交替,在接受输入从客户端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从套接字读取:错误的文件描述符
重复多次的话:
错误的叉:资源暂时不可用
出现了两次,最后:
输入/输出错误:从套接字错误读数
反复不休,直到我强行终止程序。如果我省略了任何信息需要,请让我知道,我会添加它。谢谢。
while (1) {
pid = fork();
....
i++;
}
创建了太多的子进程,最终导致失败叉。
每个孩子使用clientsockfd[i]
;其中只有两个是分配。同时i
增长趋向于无穷;第三处理已经得到一个垃圾槽(它也是一个外的绑定访问,因此UB),这解释了IO错误。
而不是考虑建立该客户一次,
while (1) {
doprocessing(clientsockfd[0]);
doprocessing(clientsockfd[1]);
}
在主线。