从套接字冻结中读取

Read from socket freeze

本文关键字:读取 冻结 套接字      更新时间:2023-10-16

我有问题,而从服务器上的客户端读取数据。read()函数总是在读取所有数据后冻结(阻塞)并等待更多的数据,这对我来说是不希望的。

服务器程序:

   soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
   struct sockaddr_in sin;  
   sin.sin_family = AF_INET;  
   sin.sin_port = htons(port);   
   sin.sin_addr.s_addr = INADDR_ANY; 
   bind(soc, (struct sockaddr*) &sin, sizeof(sin));
   if (listen(soc, MAX))
      return;
   int socc;               // socket for clinet     
   while (1) {
      if ((socc = accept(soc, (struct sockaddr *) &sin, sinlen)) < 0)
         break;
      while ((result = read(socc, pointer, SIZE)) > 0) {
         // after the data are readed, read function will block
      }
      // do some stuff and write reply to client => will never done
   }

客户端程序:

   ...
   soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)  
   struct sockaddr_in socketAddr;
   socketAddr.sin_family = AF_INET;
   socketAddr.sin_port = htons(port);
   memcpy(&(socketAddr.sin_addr), host->h_addr, host->h_length);
   if (connect(soc, (sockaddr *)&socketAddr, sizeof(socketAddr)) == -1)  
      return;
   if (write(soc, req.c_str(), strlen(req.c_str())) < 0)
      return;

主要的问题是,我不知道有多少数据将客户端发送到服务器,所以服务器应该从套接字读取所有的数据,之后没有什么来,离开读取周期。但是服务器读取整个消息(例如30字节)并等待更多(但是没有更多)。由于客户端正在等待服务器的回复,所以套接字仍然打开。

您需要使套接字非阻塞。在这种情况下,如果没有任何东西可读,则读取将立即退出,并出现特定的错误。

查看C- Unix Sockets -非阻塞读取

如前所述,使用非阻塞或为套接字添加RCV_TIMEOUT

struct timeval tv;
tv.tv_sec = 30;  /* 30 Secs Timeout */
setsockopt(sockid, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));