Boost框架中默认就提供了针对TCP流传输的支持,该功能可以用来进行基于文本协议的通信,也可以用来实现自定义的协议。一般tcp::iostream
会阻塞当前线程,直到IO操作完成。
首先来看服务端代码,如下所示在代码中首先通过GetFileSize
读取文件行数,当有了行数我们就可以使用循环的方式依次调用acceptor.accept(*tcp_stream.rdbuf())
接收客户端的相应请求,并使用<<
符号向建立了链接的文件内追加字符串数据。
#include <iostream>
#include <fstream>
#include <boost/asio.hpp>using namespace std;
using namespace boost;
using namespace boost::asio;// 利用流获取文件大小
long GetFileSize(std::string filename)
{long ref_kb;std::ifstream ptr(filename, std::ios::in | std::ios::binary);if (ptr.is_open() == true){ptr.seekg(0, std::ios::end); // 移动到末尾ref_kb = ptr.tellg(); // 获取字节数ptr.close();return ref_kb;}return 0;
}// 一次性读入,并循环输出
void ReadAllFile(std::string filename)
{char *buffer;long size;std::ifstream ptr(filename, std::ios::in | std::ios::binary | std::ios::ate);size = ptr.tellg();std::cout << "总大小: " << size << std::endl;ptr.seekg(0, std::ios::beg);buffer = new char[size];ptr.read(buffer, size);ptr.close();// 循环输出逐字节输出for (int x = 0; x < size; x++){if (buffer[x] != '\0'){std::cout << buffer[x];}}delete[] buffer;
}// 每次读入一行,并输出
void ReadLineFileA(std::string filename)
{std::ifstream ptr(filename);std::string string;while (std::getline(ptr, string)){std::cout << string.c_str() << std::endl;}
}void ReadLineFileB(std::string filename)
{char buffer[1024];std::fstream ptr;ptr.open(filename, std::ios::in | std::ios::binary);if (ptr.is_open() == true){while (!ptr.eof()){// 该行长度到达1024或者遇到\n则结束ptr.getline(buffer, 1024, '\n');std::cout << buffer << std::endl;}}
}// 获取文本总行数
int GetFileLine(std::string filename)
{char buffer[1024];std::fstream ptr;int line_count = 0;ptr.open(filename, std::ios::in | std::ios::binary);if (ptr.is_open() == true){while (!ptr.eof()){ptr.getline(buffer, 1024, '\n');line_count = line_count + 1;}}return line_count;
}int main(int argc, char *argv[])
{std::string file_path = "d://lyshark.txt";// 获取行号int count = GetFileLine(file_path);std::cout << "行数: " << count << std::endl;// 发送数据流io_service io;ip::tcp::endpoint ep(ip::tcp::v4(), 6666);ip::tcp::acceptor acceptor(io, ep);std::ifstream ptr(file_path);std::string get_string;while (std::getline(ptr, get_string)){ip::tcp::iostream tcp_stream;acceptor.accept(*tcp_stream.rdbuf());tcp_stream << get_string.c_str();}std::system("pause");return 0;
}
与服务端相比,客户端的代码则显得非常简单,在代码中我们只需要通过ip::tcp::iostream tcp_stream
链接到服务端,并通过调用getline
即可每次在流中获取一行数据,由于我们循环了3次,所有也就是只读取前三行。
#include <iostream>
#include <boost/asio.hpp>using namespace std;
using namespace boost::asio;
using namespace boost::system;int main(int argc, char *argv[])
{// 循环从流中读入,前三行for (int i = 0; i < 3; ++i){ip::tcp::iostream tcp_stream("127.0.0.1", "6666");string str;getline(tcp_stream, str);cout << str << endl;}std::system("pause");return 0;
}
读者可自行编译并运行上述代码片段,则可看到如下图所示的输出信息;