【问题标题】:C - read() never blocks on the server sideC - read() 永远不会在服务器端阻塞
【发布时间】:2012-11-07 20:04:32
【问题描述】:

我正在为一个项目创建一个游戏,它带有一个高分服务器,游戏可以在其中发送命令以保存新的高分、获得前 10 名等等。我遇到的问题是,在游戏向服务器发送了几个命令后,它们执行得非常好,即使游戏没有发送任何东西,read() 的调用也会一直收到null

我已经四处寻找解决方案,并检查了以下内容并没有问题:

1- 创建任何套接字时,我检查if (sockfd==-1) 并打印错误并退出
2- 我在每个套接字上显式启用了阻塞模式
3- 我测试了所有的套接字

if(n < 0){  
   perror("Read Error:");
}  

它从来没有进入这里,但我改为

if(n == 0){  
   perror("Read Error:");
}  

我得到了错误的地址!有关如何让读取功能等待游戏实际执行发送的任何帮助?

这是失败的发送和读取代码:

服务器:

listen(sock, 5);
clientlength = sizeof(client_add); 
newsock = accept(sock, (struct sockaddr *) &client_add, &clientlength);
if(newsock < 0){
  printf("Couldn't accept\n");
}
while(1){
  bzero(buffer, 300);
  ioctl(newsock, FIONBIO, 0);  
  n= read(newsock, buffer, 299);
  if(n == 0){  
    perror("Read Error:");
  } 
  if(n<0){
    printf("Error while reading from socket\n");
  }
  printf("Received: %s\n",buffer);
  //send to function that processes the string 
  dothemagic(buffer);
}

发送消息的示例:

strcpy(buffer, "gettop5");   
n = write(sock,buffer,strlen(buffer));
if (n < 0){ 
  printf("Writing to socket was unsuccessful\n");
}

【问题讨论】:

  • Errno(和 perror)仅在系统功能失败后才有效。返回零的读取不是失败的系统调用,因此 errno 包含垃圾。另外:检查 EINTR / EAGAIN,然后重试。

标签: c sockets client


【解决方案1】:

最大的问题是您的 printf/perror 只打印一条消息,但随后继续执行(使用归零的缓冲区...);你应该打印一个错误,然后从循环中中断/退出程序/任何合适的。 就像 wildplasser 指出的那样,n==0 不是错误。

如果您仍然无法解决问题,请尝试使用short, self contained, correct example -- 令人印象深刻的是,只需将 sscce 放在一起,您就会发现问题的频率!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    相关资源
    最近更新 更多