首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我的服务器无缘无故地暂停,直到我杀死客户端

我的服务器无缘无故地暂停,直到我杀死客户端
EN

Stack Overflow用户
提问于 2015-01-23 02:11:15
回答 1查看 43关注 0票数 0

当我同时运行客户端和服务器时,我得到的结果是:

在服务器上

服务器已打开

客户端:接受XXX.X.X.X (这是程序暂停,直到我在客户端输入ctrl+C为止),我尝试进入

我在客户端AI选择时进入:剪刀

AI :胜率为0,失败率为0,平局比为1,而客户端AI选择:剪刀

AI:胜率为0,失败率为0,平局率为2

在客户端上

代码语言:javascript
复制
1)--> Paper
2)--> Scissor
3)--> Rock
4)--> Quit

^C

我的代码:

服务器:

代码语言:javascript
复制
int main(int argc, char *argv[]){
 printf("\nServer is on\n");

 int sockfd, newsockfd, portno;
 socklen_t clilen;
 int Client_Choice;
 struct sockaddr_in serv_addr, cli_addr;
 int n,Who_Wins;
 int ai_wins=0,ai_looses=0,ties=0,total=0,ai_win_ratio=0,ai_looses_ratio=0,ai_ties_ratio;
 time_t t;
 srand((unsigned) time(&t));                                               

 if (argc < 2) {                                                            
     fprintf(stderr,"\nERROR, no port provided\n");                           
     exit(1);                                                               
 }

 sockfd = socket(AF_INET, SOCK_STREAM, 0);                                  

 if (sockfd < 0){                                                           
    error("\nERROR opening socket\n",sockfd);                                         
 }

 bzero((char *) &serv_addr, sizeof(serv_addr));                              
 portno = atoi(argv[1]);                                                     
 serv_addr.sin_family = AF_INET;                                             
 serv_addr.sin_addr.s_addr = INADDR_ANY;                                    
 serv_addr.sin_port = htons(portno);                                        


 if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){  
    error("\nERROR on binding\n",sockfd);                                      
 }

 listen(sockfd,5);                                                          
 clilen = sizeof(cli_addr);

 newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);          


 if (newsockfd < 0){                                                        
      error("\nERROR on accept\n",sockfd);                                     
 }

char *cli_IP = malloc(sizeof(cli_addr.sin_addr.s_addr));                    

if (!cli_IP){                                                               
    error("\nCould not allocate memory for conversion.\n",sockfd);           
}

inet_ntop( AF_INET , &cli_addr.sin_addr.s_addr , cli_IP , INET_ADDRSTRLEN );

printf("\nClient: %s accepted\n",cli_IP);                                    

printf("I try to get in while");

while(Client_Choice!=4){

    printf("I get in while");

    n= read( newsockfd, &Client_Choice, sizeof(Client_Choice) );        
    if(n < 0) {                                                             
        error("\nERROR reading from socket\n",sockfd);                                                        
    }
    .
    .
    .
}
close(newsockfd);                                                          
close(sockfd);                                                              
return 0;

}

客户端

代码语言:javascript
复制
int main(int argc, char *argv[]){

int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;

int send;
if (argc < 3) {
   fprintf(stderr,"usage %s hostname port\n", argv[0]);
   exit(0);
}

portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0) {
    error("ERROR opening socket\n");
}

server = gethostbyname(argv[1]);

if (server == NULL) {
    fprintf(stderr,"ERROR, no such host\n");
    exit(0);
}

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;

bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);

if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
    error("ERROR connecting\n");
}

while(send < 1 ||send > 4){

    printf("\n\t1)--> Paper\n\t2)--> Scissor\n\t3)--> Rock\n\t4)--> Quit\n");
    scanf("%d",&send);
    n = write(sockfd,&send,sizeof(send));

    if (n < 0){ 
     error("ERROR writing to socket\n");
    }    

    n = read(sockfd,&send,sizeof(send));

    if (n == 0){ 
         error("ERROR reading from socket\n");
    }
}
close(sockfd);

return 0;

}

EN

回答 1

Stack Overflow用户

发布于 2015-01-23 22:36:18

您的服务器在等待来自客户端的消息时被阻塞。您没有为处理多个客户端保留资源,只有一个进程为一个客户端提供服务(使用accept(2)中的连接套接字)。这就是它看起来阻塞的原因。在正常的服务器场景中,一个新进程由fork(2)系统调用产生,用于处理从accept(2)获得的套接字,同时主进程继续在用于接受新连接的套接字上接受(2)(2)连接。由于您正在处理服务器中的两个套接字,但是没有注意到 accept (2)连接进入的套接字描述符,它看起来被阻塞了,但实际上它已经准备好接受来自活动客户端的命令。这就是所谓的顺序服务器(在第一个服务器终止之前,它不允许连接)。

顺便说一句,在第一个while (send < 1 || send > 4)语句中使用之前,send是未初始化的,因此,如果您将其随意等于2(例如),则根本不会将客户端代码放入while中。这只是一个要点,可能还会有更多。为什么在服务器和客户端之间交换的消息类型使用不同的名称?这使得搜索错误变得更加困难。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28095824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档