简体   繁体   English

C ++ Socket接收需要很长时间

[英]c++ Socket receive takes a long time

I am writing the client side of the Socket. 我正在写Socket的客户端。 When there is something to read my code works fine but when there is nothing to read, the recv never returns. 当有什么要读取的代码时,我的代码可以正常工作,但是当没有任何要读取的代码时,recv将永远不会返回。 Help please. 请帮助。

Code: 码:

m_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in dest;

if ( m_socket )
{
  memset(&dest, 0, sizeof(dest));                /* zero the struct */
  dest.sin_family = AF_INET;
  dest.sin_addr.s_addr = inet_addr(address); /* set destination IP number */ 
  dest.sin_port = htons(port);

  if (connect(m_socket, (struct sockaddr *)&dest, sizeof(struct sockaddr)) == SOCKET_ERROR)
  {
    return false;
  }
  else
  {
    std::vector<char> inStartup1(2);
    int recvReturn = recv(Socket, &inStartup1.at(0), inStartup1.size(), 0);
  }

recv is a blocking call. recv是一个阻止呼叫。 This would help you:- 这将帮助您:-

The recv() call is normally used only on a connected socket.It returns the length of the message on successful completion. recv()调用通常仅在连接的套接字上使用,成功完成后返回消息的长度。 If a message is too long to fit in the supplied buffer, excess bytes may be discarded DEPENDING on the type of socket the message is received from. 如果消息太长而无法容纳在提供的缓冲区中,则多余的字节可能会被丢弃,具体取决于接收消息的套接字类型。

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking, in which case the value -1 is returned and the external variable errno is set to EAGAIN or EWOULDBLOCK. 如果套接字上没有可用的消息,则接收调用将等待消息到达,除非套接字未阻塞,在这种情况下,将返回值-1,并且外部变量errno设置为EAGAIN或EWOULDBLOCK。 The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested. 接收呼叫通常返回不超过请求数量的任何可用数据,而不是等待接收请求的全部数量。

Taking this one step further, on a server this is how you would correctly handle a connection (socket or serial port does not matter): 更进一步,在服务器上,这是正确处理连接的方式(套接字或串行端口无关紧要):

  1. make the socket/port non-blocking: this is the first important step; 使套接字/端口无阻塞:这是重要的第一步; it means that recv() will read what is available (if anything) and return the number of read bytes or -1 in case of an error. 这意味着recv()将读取可用的内容(如果有的话),并返回读取的字节数;如果发生错误,则返回-1。
  2. use select(), with a timeout, to find out when data becomes available. 使用带有超时的select()来查找数据何时可用。 So now you wait for a certain amount of time for data to become available and than read it. 因此,现在您要等待一定时间才能使数据可用并读取数据。
  3. The next problem to handle is making sure you read the full message. 要处理的下一个问题是确保您阅读了完整的消息。 Since there is no guarantee that the whole message will be available when you call recv(), you need to save whatever is available and go back to select() and wait for the next data to become available. 由于不能保证在调用recv()时整个消息都可用,因此需要保存所有可用内容,然后返回到select()并等待下一个数据可用。
  4. Put everything in a while(cond) construct to make sure you read all the data. 将所有内容放入while(cond)构造中,以确保您读取了所有数据。

The condition in the while is the only thing left to figure out - you either know the length of the expected message or you use some delimiters to mark the end of the message. 一会儿,这个条件是唯一需要弄清楚的-您要么知道预期消息的长度,要么使用一些定界符来标记消息的结尾。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM