19.13 Boost Asio 发送TCP流数据

简介: Boost框架中默认就提供了针对TCP流传输的支持,该功能可以用来进行基于文本协议的通信,也可以用来实现自定义的协议。一般`tcp::iostream`会阻塞当前线程,直到IO操作完成。首先来看服务端代码,如下所示在代码中首先通过`GetFileSize`读取文件行数,当有了行数我们就可以使用循环的方式依次调用`acceptor.accept(*tcp_stream.rdbuf())`接收客户端的相应请求,并使用`<<`符号向建立了链接的文件内追加字符串数据。

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;
}

读者可自行编译并运行上述代码片段,则可看到如下图所示的输出信息;

相关文章
19.10 Boost Asio 同步文件传输
在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含`goodbye lyshark`关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这种方式也存在一个有点,那就是无需确定文件长度,因为无需读入文件所以在传输速度上要快一些,尤其是面对大文件时。服务端代码如下所示,在代码中我们分别封装实现`recv_remote_file`该函数用于将远程特定目录下的文件拉取到本地目录下,而`send_local_file`函数则用于将一个本地文件传输到对端主机上,这两个函数都接收三个参数,分别是套接字句柄,本地
99 0
19.10 Boost Asio 同步文件传输
|
5月前
|
网络协议 应用服务中间件 网络性能优化
解析TCP /UDP协议的 socket 调用的过程
【6月更文挑战第2天】该文介绍了传输层的两种主要协议TCP和UDP的区别。TCP是面向连接、可靠的,提供顺序无错的数据传输,而UDP则是无连接、不可靠的,不保证数据顺序或不丢失。
|
6月前
|
存储 传感器 网络协议
通信协议缓冲区管理全景:TCP、UDP、ZMQ、DBus、SSL、SOME/IP通讯协议的缓冲区解析...
通信协议缓冲区管理全景:TCP、UDP、ZMQ、DBus、SSL、SOME/IP通讯协议的缓冲区解析...
268 0
|
6月前
|
存储 网络协议 Java
TCP流套接字编程
TCP流套接字编程
|
消息中间件 网络协议
ZMQ与TCP的区别
ZMQ与TCP的区别
ZMQ与TCP的区别
|
网络协议 Shell Linux
什么是 TCP 流?
在一些技术文档,特别是 Wireshark 相关的文档中,“TCP 流”是一个很常见的词汇。 它是什么意思呢?为什么叫“流”,难道跟水有关吗?
469 0
|
网络协议 C++
C++流的streambuf详解及TCP流的实现
streambuf是C++流(iostream)与流实体(文件、标准输入输出等)交互的桥梁,文件流和字符串流是C++标准库已经提供了的,现在我的目标是实现一个使用TCP协议通信的socket流...
4217 0