一、Socket创建和连接

一、Socket创建和连接Asio 起源于 Boost 库 是一款专为网络 I O 定时器串行端口通信设计的库 提供了同步和异步的编程模型 用以简化网络和低级 I O 的操作

大家好,欢迎来到IT知识分享网。

C++网络编程(asio)

点击查看代码

1、Asio概述

​ Asio起源于Boost库,是一款专为网络I/O定时器串行端口通信设计的库,提供了同步和异步的编程模型,用以简化网络和低级I/O的操作。asio封装了操作系统一些底层机制如select、socket、poll/epoll等,以实现异步IO模型

Asio异步处理,可以使任务触发时不需要等待,继续往下执行其他任务,直至其它线程将处理完成,并回调通知此线程。

下面将使用Boost.Asio库对网络编程进行重写

2、网络编程基本流程

服务器端

  1. socket : 创建socket对象
  2. bind : 绑定本机ip+port
  3. listen : 监听。若监听到信号,建立连接
  4. accept : 接受客户端的连接请求,返回一个新的Socket对象用于与客户端通信。原因是现实中服务器对应多个客户端,每个客户端对应相应的socket对象进行收发信息
  5. read、write : 收发信息

客户端

  1. socket : 创建socket对象
  2. connect : 根据服务器ip+port,发送连接请求
  3. write、read : 发收信息

请添加图片描述 1、创建终端节点

概念:所谓终端节点就是用来通信的端对端的节点,可以通过ip地址和端口构造,其他节点可以连接这个终端节点做通信.

客户端,我们可以通过对端(服务器端)的ip和端口构造一个endpoint,用这个endpoint和其通信。

int client_end_point() { 
     std::string raw_ip_address = "127.0.0.1"; unsigned short port_num = 3333; boost:system::error_code ec; // 错误码 // asio提供转换地址 asio::ip::address ip_address = asio::ip::address::from_string(raw_ip_address, ec); if (ec.value() != 0) { 
     std::cout << "Failed to parse the IP Address. Error code = " << ec.value() << ". Message is " << ec.message(); return ec.value(); } // bind(ip+address) asio::ip::tcp::endpoint ep(ip_address, port_num); return 0; } 

此时,ep 对象表示客户端端点,可以用于连接指定的服务器上的 TCP。然而,代码并没有显示实际连接过程或与服务器的任何通信,因此它只是为将来使用而准备端点。

服务端,则只需根据本地地址绑定就可以生成endpoint

int server_end_point() { 
     unsigned short port_num = 3333; // 服务器将监听主机上的所有可用 IPv6 地址 asio::ip::address ip_address = asio::ip::address_v6::any(); asio::ip::tcp::endpoint ep(ip_address, port_num); return 0; } 

此时,ep 对象表示一个可以用于监听传入连接请求的 TCP 端点,其 IP 地址为所有可用的 IPv6 地址,而端口号由函数参数 port_num 决定。

2、创建socket

服务器和客户端socket一致,创建socket分为4步,

  1. 创建上下文io_context
  2. 选择协议
  3. 生成socket
  4. 打开socket
int create_tcp_socket() { 
     // 上下文告诉socket,此socket为ioc服务 asio::io_context ioc; // IPV4的TCP协议 asio::ip::tcp protocol = asio::ip::tcp::v4(); asio::ip::tcp::socket socket(ioc); boost::system::error_code ec; socket.open(protocol, ec); if (ec.value() != 0) { 
     std::cout << "Failed to open the socket. Error code = " << ec.value() << ". Message is " << ec.message(); } return 0; } 

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个 TCP 套接字

3、创建监听socket

服务端,我们还需要生成一个acceptorsocket,用来监听接收新来自客户端的连接

int create_acceptor_socket() { 
     asio::io_context ioc; asio::ip::tcp::acceptor a(ioc, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 3333)); return 0; } 

这段代码演示了如何使用 Boost.Asio 库来创建并打开一个监听套接字,用于接受传入的连接请求。监听套接字通常用于服务器端,用于等待客户端的连接。

4、绑定accpet监听套接字

对于accept类型的socket服务器要将其绑定到指定的断点,所有连接这个端点的连接都可以被接收到。

  • 创建端点(ip+端口)。
  • 创建监听套接字acceptor
  • 绑定监听套接字acceptor
int bind_acceptor_socket() { 
     unsigned short port_num = 3333; asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(), port_num); asio::io_context ioc; asio::ip::tcp::acceptor acceptor(ioc, ep.protocol()); boost::system::error_code ec; acceptor.bind(ep, ec); if (ec.value() != 0) { 
     std::cout << "Failed to bind the acceptor socket. Error code = " << ec.value() << ". Message is " << ec.message(); } return 0; } 

这段代码展示了如何使用 Boost.Asio 库创建一个绑定到指定 IP 地址和端口的监听套接字,用于等待客户端的连接请求。

5、连接指定的端点

作为客户端可以连接服务器指定的端点进行连接

  • 创建端点(ip+端口)。
  • 创建通信socket套接字。
  • 通信socket套接字连接到指定端点。
int connect_to_end() { 
     std::string raw_ip_address = "192.168.1.124"; unsigned short port_num = 3333; try { 
     asio::ip::tcp::endpoint ep(asio::ip::address::from_string(raw_ip_address), port_num); asio::io_context ioc; asio::ip::tcp::socket socket(ioc, ep.protocol()); socket.connect(ep); } catch (system::system_error &e) { 
     std::cout << "Error connect! Error code = " << e.code() << ". Message: " << e.what(); return e.code().value(); } return 0; } 

这段代码用于在客户端创建套接字并连接到服务器,以便与服务器进行数据交换。

6、服务器接收连接

当有客户端连接时,服务器需要接收连接:

  • 创建端点(ip+端口)。
  • 创建监听套接字acceptor
  • 绑定监听套接字acceptor
  • 监听队列大小。
  • 创建与客户端通信套接字。
  • 接收客户端连接。
int accept_int_connection() { 
     // 缓冲来不及接收的信息 const int BACKLOG_SIZE = 30; unsigned short port_num = 3333; asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(), port_num); asio::io_context ioc; try { 
     asio::ip::tcp::acceptor acceptor(ioc, ep.protocol()); acceptor.bind(ep); acceptor.listen(BACKLOG_SIZE); asio::ip::tcp::socket socket(ioc); acceptor.accept(socket); } catch (system::system_error& e) { 
     std::cout << "Error accept! Error code = " << e.code() << ". Message: " << e.what(); return e.code().value(); } return 0; } 

这段代码用于在服务器端创建接受套接字,绑定端点并开始监听连接请求,然后处理下一个连接请求并与客户端建立连接,以便进行数据交换。


参考:
恋恋风辰blog
森明帮大于黑虎帮
哔哩哔哩



免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/109754.html

(0)
上一篇 2026-02-04 19:34
下一篇 2026-02-04 20:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信