我已经使用boost::asio
实现了一个TCP服务器。该服务器使用basic_stream_socket::read_some
函数读取数据。我知道read_some
并不能保证提供的缓冲区在返回之前就已满。使用boost :: asio :: read_some在TCP/IP中丢弃数据?
在我的项目中,我发送由分隔符分隔的字符串(如果有的话)。在客户端,我使用WinSock::send()
函数发送数据。现在我的问题是在服务器端,我无法获得从客户端发送的所有字符串。我的怀疑是read_some
正在接收一些数据并由于某种原因丢弃了剩余数据。再次在下一次调用它接收另一个字符串。
TCP/IP真的有可能吗?
我试图使用async_receive
,但这是吃掉了我所有的CPU,也因为缓冲区必须通过回调函数清除它,导致我的程序中严重的内存泄漏。 (我正在使用IoService::poll()
来呼叫处理程序,与呼叫率async_read()
相比,该处理程序的呼叫速度很慢)。
我再次尝试使用免费函数read
,但这不会解决我的目的,因为它阻塞了我提供的缓冲区大小的太多时间。
我之前的服务器实现是使用WinSock API
,我可以使用WinSock::recv()
接收所有数据。 请给我一些线索,以便我可以使用boost::asio
接收完整的数据。
这里是我的TCPSocket服务器端螺纹环
void
TCPObject::receive()
{
if (!_asyncModeEnabled)
{
std::string recvString;
if (!_tcpSocket->receiveData(_maxBufferSize, recvString))
{
LOG_ERROR("Error Occurred while receiving data on socket.");
}
else
_parseAndPopulateQueue (recvString);
}
else
{
if (!_tcpSocket->receiveDataAsync(_maxBufferSize))
{
LOG_ERROR("Error Occurred while receiving data on socket.");
}
}
}
receiveData的()
bool
TCPSocket::receiveData(unsigned int bufferSize, std::string& dataString)
{
boost::system::error_code error;
char *buf = new char[bufferSize + 1];
size_t len = _tcpSocket->read_some(boost::asio::buffer((void*)buf, bufferSize), error);
if(error)
{
LOG_ERROR("Error in receiving data.");
LOG_ERROR(error.message());
_tcpSocket->close();
delete [] buf;
return false;
}
buf[len] ='\0';
dataString.insert(0, buf);
delete [] buf;
return true;
}
receiveDataAsync在TCP套接字
bool
TCPSocket::receiveDataAsync(unsigned int bufferSize)
{
char *buf = new char[bufferSize + 1];
try
{
_tcpSocket->async_read_some(boost::asio::buffer((void*)buf, bufferSize),
boost::bind(&TCPSocket::_handleAsyncReceive,
this,
buf,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
//! Asks io_service to execute callback
_ioService->poll();
}
catch (std::exception& e)
{
LOG_ERROR("Error Receiving Data Asynchronously");
LOG_ERROR(e.what());
delete [] buf;
return false;
}
//we dont delete buf here as it will be deleted by callback _handleAsyncReceive
return true;
}
非同步接收处理程序
void
TCPSocket::_handleAsyncReceive(char *buf, const boost::system::error_code& ec, size_t size)
{
if(ec)
{
LOG_ERROR ("Error occurred while sending data Asynchronously.");
LOG_ERROR (ec.message());
}
else if (size > 0)
{
buf[size] = '\0';
emit _asyncDataReceivedSignal(QString::fromLocal8Bit(buf));
}
delete [] buf;
}
客户端sendData函数。
sendData(std::string data)
{
if(!_connected)
{
return;
}
const char *pBuffer = data.c_str();
int bytes = data.length() + 1;
int i = 0,j;
while (i < bytes)
{
j = send(_connectSocket, pBuffer+i, bytes-i, 0);
if(j == SOCKET_ERROR)
{
_connected = false;
if(!_bNetworkErrNotified)
{
_bNetworkErrNotified=true;
emit networkErrorSignal(j);
}
LOG_ERROR("Unable to send Network Packet");
break;
}
i += j;
}
}
如果您需要帮助,请发布您的代码。包括服务器代码以及客户端代码,因为问题可能在一个或两个中。 – 2013-02-12 14:01:32
用代码更新。 – 2013-02-12 14:38:06