我在设置客户端 - 服务器连接方面很新,我遇到了在两台计算机之间发送数据的问题。我的代码运行良好,#34; localhost"但是有两台计算机通过网络,它会在某处崩溃。在localhost中,我可以传输22 MB数据,这是我最大的数据文件。
对于两台计算机的连接: 我有一个小例子来传输数据,它的数据量大约是11 kb。这个例子在这里也运作良好。然而,下一个更大的例子,大小为0f 230 kb崩溃。
我正在使用同步TCP。
SERVER:
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4( ), 40986 ) );
CDBReader* sender = CDBReader::getInstance( );
for ( ;; )
{
tcp::socket socket( io_service );
mySocket = &socket;
acceptor.accept( *mySocket );
}
客户端:
try
{
boost::asio::io_service io_service;
tcp::resolver resolver( io_service );
tcp::resolver::query query( serverName, "40986" );
tcp::resolver::iterator endpoint_iterator = resolver.resolve( query );
tcp::socket socket( io_service );
mySocket = &socket;
boost::asio::connect( *mySocket, endpoint_iterator );
boost::system::error_code error;
}
这是我创建连接的方式。
这是我在Server中用来发送数据的功能。根据数据量,我分成几部分后发送。
void vtkCDBConnectorSource::sendString( std::string message )
{
std::cout << "I am in sendString" << std::endl;
int loopCounter = message.size() / charArraySize + 1;
size_t mSize = message.size();
std::stringstream SStream;
SStream << loopCounter;
std::string noLoop = SStream.str( );
// std::cout << "loopCounter = " << loopCounter << std::endl;
if(loopCounter >= 10 && loopCounter < 100)
{
std::stringstream digitNumberSizeStream;
digitNumberSizeStream << 2;
std::string digitNumberSize = digitNumberSizeStream.str( );
digitNumberSizeStream.str(std::string());
digitNumberSizeStream.clear();
// std::cout << "digitNumberSize = " << digitNumberSize << std::endl;
// std::cout << "noLoop = " << noLoop << std::endl;
size_t s10 = mySocket->send( boost::asio::buffer( digitNumberSize ) );
size_t s11 = mySocket->send( boost::asio::buffer( noLoop ) );
}
else if( loopCounter >= 100 && loopCounter < 1000)
{
std::stringstream digitNumberSizeStream;
digitNumberSizeStream << 3;
std::string digitNumberSize = digitNumberSizeStream.str( );
digitNumberSizeStream.str(std::string());
digitNumberSizeStream.clear();
// std::cout << "digitNumberSize = " << digitNumberSize << std::endl;
// std::cout << "noLoop = " << noLoop << std::endl;
size_t s10 = mySocket->send( boost::asio::buffer( digitNumberSize ) );
size_t s11 = mySocket->send( boost::asio::buffer( noLoop ) );
}
else if( loopCounter >= 1000)
{
std::stringstream digitNumberSizeStream;
digitNumberSizeStream << 4;
std::string digitNumberSize = digitNumberSizeStream.str( );
digitNumberSizeStream.str(std::string());
digitNumberSizeStream.clear();
// std::cout << "digitNumberSize = " << digitNumberSize << std::endl;
// std::cout << "noLoop = " << noLoop << std::endl;
size_t s10 = mySocket->send( boost::asio::buffer( digitNumberSize ) );
size_t s11 = mySocket->send( boost::asio::buffer( noLoop ) );
}
else
{
std::stringstream digitNumberSizeStream;
digitNumberSizeStream << 1;
std::string digitNumberSize = digitNumberSizeStream.str( );
digitNumberSizeStream.str(std::string());
digitNumberSizeStream.clear();
// std::cout << "digitNumberSize = " << digitNumberSize << std::endl;
// std::cout << "noLoop = " << noLoop << std::endl;
size_t s10 = mySocket->send( boost::asio::buffer( digitNumberSize ) );
size_t s11 = mySocket->send( boost::asio::buffer( noLoop ) );
}
SStream.str( std::string( ) );
SStream.clear( );
int i = 0;
while( i < loopCounter )
{
int secLoop = 0;
if( mSize >= charArraySize)
{
secLoop = charArraySize;
mSize = mSize - secLoop;
}
else
{
secLoop = mSize;
}
std::string tempMessage;
for( size_t j=0; j<secLoop; j++)
{
tempMessage.push_back( message[charArraySize*i + j] );
}
std::stringstream messageSizeStream;
messageSizeStream << secLoop;
std::string messageSize = messageSizeStream.str( );
size_t dataDigitSize = messageSizeStream.str().size();
std::stringstream messageDigitStream;
messageDigitStream << dataDigitSize;
std::string messageDigit = messageDigitStream.str( );
// std::cout << "messageDigit = " << messageDigit << std::endl;
// std::cout << "messageSize = " << messageSize << std::endl;
size_t s12 = mySocket->send( boost::asio::buffer( messageDigit ) );
size_t s13 = mySocket->send( boost::asio::buffer( messageSize ) );
size_t s14 = mySocket->send( boost::asio::buffer( tempMessage ) );
messageSizeStream.str( std::string( ) );
messageSizeStream.clear( );
++i;
}
// std::cout<<"SendString Finished"<<std::endl;
mySendStream.str( std::string( ) );
mySendStream.clear( );
}
这是客户端接收数据的功能:
size_t vtkCDBConnectorSource::DataContainer( )
{
std::cout << "I am in DataContainer" << std::endl;
char* sizeOfLoop = new char[10];
char* noOfLoops= new char[100];
size_t dataLength;
size_t loopsizeDigit = mySocket->receive( boost::asio::buffer( sizeOfLoop, 1 ) );
std::stringstream lStream;
lStream << sizeOfLoop;
size_t numberOfloops;
lStream >> numberOfloops ;
lStream.str(std::string());
lStream.clear();
std::cout<<"Number of Digits for Loops= "<<numberOfloops<<std::endl;
size_t sizeDigit = mySocket->receive( boost::asio::buffer(noOfLoops, numberOfloops ) );
std::stringstream RStream;
RStream << noOfLoops;
size_t loopSize;
RStream >> loopSize ;
RStream.str(std::string());
RStream.clear();
std::cout << "loopSize = " << loopSize << std::endl;
int i = 0;
while( i < loopSize )
{
char* dataDigit= new char[100];
size_t sizeDataDigit = mySocket->receive( boost::asio::buffer( dataDigit, 1 ) );
RStream << dataDigit;
size_t digitNumber;
RStream >> digitNumber;
RStream.str(std::string());
RStream.clear();
char* dataSize = new char[100];
// std::cout << "digitNumber = " << digitNumber << std::endl;
size_t sizeData = mySocket->receive( boost::asio::buffer( dataSize, digitNumber ) );
RStream << dataSize;
size_t dataAmount;
RStream >> dataAmount;
RStream.str(std::string());
RStream.clear( );
char* data= new char[100000];
// std::cout << "dataAmount = " << dataAmount << std::endl;
dataLength = mySocket->receive( boost::asio::buffer( data, dataAmount ) );
std::cout << "dataLength = " << dataLength << std::endl;
int k = 0;
while ( dataLength-- > 0 ) // maybe need to divide by 2
{
myReceivedStream << data[k++];
}
delete[] data;
delete[] dataDigit;
delete[] dataSize;
++i;
}
delete[] sizeOfLoop;
delete[] noOfLoops;
std::cout << " ---- Data Container FINISHED--- " << std::endl;
return dataLength;
}
我希望我可以告诉我的问题,如果有任何不清楚的地方,请告诉我。 提前感谢您的帮助。
答案 0 :(得分:1)
此代码是未定义的行为:
tcp::socket socket( io_service );
mySocket = &socket;
您正在tcp::socket
块的范围内创建try
,然后将其存储在mySocket
中,该地址位于此范围之外。离开try
块后,tcp::socket
将被销毁,mySocket
仍然指向已销毁的对象。
它可能会工作一段时间,直到某些其他代码运行并覆盖被破坏的tcp::socket
对象所占用的堆栈部分。
解决此问题后,同样的问题也适用于您的io_service
;你使用对它的引用构造套接字,然后允许它被销毁,所以固定的tcp::socket
对象仍然保持对被破坏的io_service
的引用。