Boost Asio同步通信

Boost Asio同步通信,boost,boost-asio,synchronous,Boost,Boost Asio,Synchronous,我在使用asio时遇到问题。我的客户机/服务器应用程序只需要同步通信。因此,使用boost主页上synchro的示例,我设置了两个发送和接收数据的过程。其代码如下: void vReceive(tcp::socket & socket, std::string & szDest){ char szTmp_Buf [BUF_LEN + 1]; szDest = ""; std::cout << "Entering vReceive . . ."

我在使用asio时遇到问题。我的客户机/服务器应用程序只需要同步通信。因此,使用boost主页上synchro的示例,我设置了两个发送和接收数据的过程。其代码如下:

void vReceive(tcp::socket & socket, std::string & szDest){
    char szTmp_Buf [BUF_LEN + 1];
    szDest = "";
    std::cout << "Entering vReceive . . ." << std::endl;

    for (;;){
      char szBuf [BUF_LEN];
      boost::system::error_code error;
      uInt uiBytes_Recv = socket.read_some(boost::asio::buffer(szBuf), error);
      std::cout << " Read " << uiBytes_Recv << " bytes" << std::endl;
      if (error == boost::asio::error::eof)
         break; // Connection closed cleanly by peer.
      else if (error)
         throw boost::system::system_error(error); // Some other error.

      memcpy((void*) szTmp_Buf, (void*) szBuf, uiBytes_Recv );
      szTmp_Buf[ uiBytes_Recv ] = '\0';
      szDest += szTmp_Buf;
      };
      std::cout << "Received" << szDest << std::endl;
      std::cout << "Leaving vReceive . . ." << std::endl << std::endl;
   };

void vSend(tcp::socket & socket, std::string & szSrc){
    std::cout << "Entering vSend . . . " << std::endl;
    std::cout << "Sending " << szSrc << std::endl;
    boost::system::error_code ignored_error;
    boost::asio::write(socket, boost::asio::buffer(szSrc), boost::asio::transfer_all(), ignored_error);
    std::cout << "Leaving vSend . . . " << std::endl << std::endl;
    };
然后服务器调用

std::string message = make_daytime_string();
std::string szReceived;
vSend(socket, message);
vReceive(socket, szReceived);
vSend(socket, message);
vReceive(socket, szReceived);
只是为了测试功能。问题是两个应用程序在第一次信息交换后都会冻结,正如我在下面所描述的。客户端的vReceive()过程似乎没有完成,而服务器端的vSend()完成。那么,有没有人知道可能出了什么问题

为了防止有人想复制这个问题,我将源代码完整的源代码上传到同一个服务器上,图片位于asio_problem.rar文件中(作为新成员,我可以在每篇文章中有一个超链接)

提前谢谢大家,,
丹尼尔。

我认为你的问题在于:

for (;;){
  /* snipped */

  if (error == boost::asio::error::eof)
     break; // Connection closed cleanly by peer.
  else if (error)
     throw boost::system::system_error(error); // Some other error.

  /* snipped */
}
您将无限循环,直到连接关闭(断开循环的唯一方法是从套接字接收到EOF错误),但
vSend
从不关闭套接字。这意味着您的客户机中的
vReceive
将永远等待,始终期待更多的数据。在
vSend
中放置一个
socket.close()
,应该可以很好地完成这个任务

当然,这意味着您的客户端和服务器需要在每次分别调用
vReceive
vSend
后重新打开套接字。如果这不可取,那么我建议使用一些其他方式,发送方通知接收方不再发送数据

我不确定您是否对通过网络发送的数据有任何限制,但在消息开头发送“数据长度”值或在消息结尾发送某种类型的“数据结束”哨兵值都会为您提供一个很好的、清晰的指示器,指示您何时停止侦听更多数据

这种方法的另一个好处是,让您有理由使用ASIO的
read_until
(或类似)功能来处理等待数据结束的逻辑

for (;;){
  /* snipped */

  if (error == boost::asio::error::eof)
     break; // Connection closed cleanly by peer.
  else if (error)
     throw boost::system::system_error(error); // Some other error.

  /* snipped */
}