【问题标题】:my server pauses at no reason until I kill the client我的服务器无缘无故暂停,直到我杀死客户端
【发布时间】:2015-03-21 15:51:50
【问题描述】:

当我同时运行客户端和服务器时,结果如下:

在服务器上

服务器开启

客户:XXX.X.X.X 已接受 (这就是程序暂停的地方,直到我在客户端输入 ctrl+C) 我试着进去

我进去一会儿 客户 AI选择:剪刀

AI:胜率 0,输率 0,平局率 1 我进去一会儿 客户 AI选择:剪刀

AI:胜率 0,输率 0,平局率 2

在客户端

1)--> Paper
2)--> Scissor
3)--> Rock
4)--> Quit

^C

我的代码:

服务器:

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;

}

客户

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;

}

【问题讨论】:

    标签: c sockets networking client server


    【解决方案1】:

    您的服务器被阻止等待来自客户端的消息。您没有为处理多个客户端保留资源,并且只有一个进程为单个客户端服务(使用来自 accept(2) 的连接套接字)。这就是它出现阻塞的原因。在正常的服务器场景中,一个新进程由 fork(2) 系统调用来处理从 accept(2) 获得的套接字,而主进程继续accept(2) 用于接受新连接的套接字上的连接。由于您正在处理服务器中的两个套接字,但没有参与 accept(2) 连接进入的套接字描述符,它似乎被阻止,但实际上它已准备好接受来自活动的命令客户。这就是所谓的顺序服务器(它不允许在第一个终止之前建立连接)。

    顺便说一句,send 在第一个 while (send &lt; 1 || send &gt; 4) 句子中使用之前是未初始化的,所以如果你随便得到它等于 2(例如),你根本不会让客户端代码进入 while。这只是一点,可能还会有更多。为什么服务器和客户端之间交换的消息类型使用不同的名称?这使得搜索错误变得更加困难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      相关资源
      最近更新 更多