第一个环境数据:Windows 7、c:\boost(1.55.0)、Microsoft Visual c++2010学习版(SP1)
这是你能想到的最简单的客户端/服务器功能版本,使用新的线路末端线路作为运输方式(请忽略缺少限制和超时!)
服务器等待,直到客户端发送"fn"
,然后将本地文本文件中修剪后的行发回客户端。最后一行只有一个点(.),表示传输结束(忽略文件中可能有一个点的事实。)
问题出在哪里
服务器上的输出显示所有行都被发送回客户端。然而,客户端显示缺少一些行。
我看不出传输哪里有可能丢失数据。
这是功能齐全的服务器代码。构建它,并在不带参数的服务器上运行。
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <iostream>
#include <boost/asio.hpp>
void writeln( boost::asio::ip::tcp::socket& socket, const std::string& text )
{
std::cout << "writeln " << text << "n" ;
boost::system::error_code error ;
boost::asio::write( socket, boost::asio::buffer( text + "n", text.length() + 1 ), boost::asio::transfer_all(), error );
}
bool readln( boost::asio::ip::tcp::socket& socket, std::string& text )
{
try
{
boost::asio::streambuf response ;
boost::asio::read_until( socket, response, "n" ) ;
std::istream response_stream( &response ) ;
std::getline( response_stream, text ) ;
if ( text != "." )
return true ;
}
catch( const std::exception& e )
{
std::cerr << e.what() << "n" ;
}
return false ;
}
static char* trim( char* line )
{
size_t len = strlen( line ) ;
while ( len > 0 && ( line[ len - 1 ] == ' ' || line[ len - 1 ] == 't' || line[ len - 1 ] == 'n' || line[ len - 1 ] == 'r' ))
len-- ;
line[ len ] = 0 ;
return line ;
}
static void f( boost::asio::ip::tcp::socket& socket )
{
std::string fname = "c:\f.txt" ;
FILE* f = fopen( fname.c_str(), "r" ) ;
if ( f != NULL )
{
char line[ 1024 ] ;
while ( fgets( line, sizeof( line ), f ) != NULL )
writeln( socket, trim( line )) ;
fclose( f ) ;
}
}
int main( int argc, char* argv[])
{
try
{
boost::asio::io_service io_service ;
boost::asio::ip::tcp::acceptor acceptor( io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8080 )) ;
for (;;)
{
boost::asio::ip::tcp::socket socket( io_service ) ;
std::string cmd ;
acceptor.accept( socket ) ;
while ( readln( socket, cmd ))
{
std::cout << cmd << "n" ;
if ( cmd == "f" )
f( socket ) ;
writeln( socket, "." ) ;
}
}
}
catch( const std::exception& e )
{
std::cerr << e.what() << "n" ;
}
return 0 ;
}
这是客户的代码。调用prog 127.0.0.1 f
查看结果。
#include "stdafx.h"
#include <boost/asio.hpp>
#include <iostream>
void writeln( boost::asio::ip::tcp::socket& socket, const std::string& text )
{
boost::system::error_code error ;
boost::asio::write( socket, boost::asio::buffer( text + "n", text.length() + 1 ), boost::asio::transfer_all(), error );
}
bool readln( boost::asio::ip::tcp::socket& socket, std::string& text )
{
try
{
boost::asio::streambuf response ;
boost::asio::read_until( socket, response, "n" ) ;
std::istream response_stream( &response ) ;
std::getline( response_stream, text ) ;
std::cout << "readln " << text << "n" ;
if ( text != "." )
return true ;
}
catch( const std::exception& e )
{
std::cerr << e.what() << "n" ;
}
return false ;
}
int main( int argc, char* argv[])
{
if ( argc > 2 )
try
{
boost::asio::io_service io_service ;
boost::asio::ip::tcp::socket socket( io_service ) ;
std::string text ;
socket.connect( boost::asio::ip::tcp::endpoint( boost::asio::ip::address::from_string( argv[ 1 ]), 8080 )) ;
writeln( socket, argv[ 2 ]) ;
while ( readln( socket, text ))
std::cout << text << "n" ;
return 0 ;
}
catch( const std::exception& e )
{
std::cerr << e.what() << "n" ;
return 1 ;
}
}
客户端版本中的bool readln( boost::asio::ip::tcp::socket& socket, std::string& text )
函数不正确。使用缓冲io,吃得比应该吃的多。
这不是最好的版本,但不是客户当前的代码:
while ( readln( socket, text ))
std::cout << text << "n" ;
它可以做到:
boost::asio::streambuf response ;
for(;;)
{
boost::asio::read_until( socket, response, "n" ) ;
std::istream response_stream( &response ) ;
std::getline( response_stream, text ) ;
if ( text == "." )
break ;
std::cout << text << "n" ;
}