在上次成功握手之后,我无法进行ssl握手。一旦连接并且握手完成,我的客户端可以长时间成功发送和接收。偶尔我会断开与服务器的连接,并显示错误“远程主机强行关闭现有连接。”。当发生这种情况时,我取消并关闭客户端上的套接字。然后我可以再次连接,但是当我启动async_handshake时,没有任何内容传输到服务器(wireshark显示没有活动)。然后我最终再次与服务器断开连接(可能是由于不活动),基本上是相同的错误“现有连接被远程主机强行关闭。”。我知道客户端在第一次断开连接之前正在发送和接收数据 - 所以不活动不是原因。一旦处于此状态,客户端每次尝试时都可以连接,但async_handshake从不传输任何内容,因此循环重复。
有什么想法吗?
以下是大部分代码:
连接:
boost::asio::async_connect( m_socket.lowest_layer(), endpoint_iterator, boost::bind(&CClientSock::handle_connect, shared_from_this(), boost::asio::placeholders::error));
和其他
void CClientSock::handle_connect(const boost::system::error_code& error) { if ( !error ) { m_socket.async_handshake( boost::asio::ssl::stream_base::client, boost::bind(&CClientSock::handle_handshake, shared_from_this(), boost::asio::placeholders::error) ); } else { CloseSocket(); m_eState = eDisconnected; } } void CClientSock::handle_handshake( const boost::system::error_code& error ) { if (!error) { BeginRead(); SendQuery(); } else { CloseSocket(); m_eState = eDisconnected; } } void CClientSock::BeginRead() { // Start an async read and always keep one going size_t bytes_transferred = BUFFER_SIZE; m_socket.async_read_some( boost::asio::buffer(rcvbuf, bytes_transferred), boost::bind(&CClientSock::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void CClientSock::SendQuery() { m_eState = eSending; m_bTMO = FALSE; size_t request_length = 0; #ifdef _USE_MODBUSTCP sndbuf [0] = 0x00; sndbuf [1] = m_bTxn; m_bTxn++; sndbuf [2] = 0x00; sndbuf [3] = 0x00; sndbuf [4] = 0x00; sndbuf [5] = 0x06; sndbuf [6] = 0x01; sndbuf [7] = 0x03; sndbuf [8] = 0x1B; sndbuf [9] = 0x59; sndbuf [10] = 0x00; sndbuf [11] = 0x01; request_length = 12; #else sndbuf [0] = 0x01; sndbuf [1] = 0x03; sndbuf [2] = 0x1B; sndbuf [3] = 0x59; sndbuf [4] = 0x00; sndbuf [5] = 0x01; sndbuf [6] = 0x52; sndbuf [7] = 0xFD; request_length = 8; #endif boost::asio::async_write(m_socket, boost::asio::buffer(sndbuf, request_length), boost::bind(&CClientSock::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void CClientSock::handle_write( const boost::system::error_code& error, size_t bytes_transferred ) { if ( !error ) { // Already have an async_read started, so do nothing here. m_eState = eReceiving; } else { CloseSocket(); m_eState = eDisconnected; } } void CClientSock::handle_read( const boost::system::error_code& error, size_t bytes_transferred ) { if ( !error ) { // start another async read BeginRead(); // An external call starts another write when we're idle m_eState = eIdle; } else { CloseSocket(); m_eState = eDisconnected; } } void CClientSock::CloseSocket() { bool bexcept = false; try { #ifdef _SSL_TEST if ( m_socket.lowest_layer().is_open() ) { m_socket.lowest_layer().cancel(); m_socket.lowest_layer().close(); } #else if ( m_socket.is_open() ) { m_socket.cancel(); m_socket.close(); } #endif } catch (std::exception& e) { bexcept = true; } }