您的位置:首页 > 新闻 > 热点要闻 > 一、Socket创建和连接

一、Socket创建和连接

2025/2/24 5:48:04 来源:https://blog.csdn.net/qq_63228903/article/details/139574044  浏览:    关键词:一、Socket创建和连接

C++网络编程(asio)

文章目录

  • C++网络编程(asio)
  • 1、Asio概述
  • 2、网络编程基本流程
    • 2、创建socket
    • 3、创建监听socket
    • 4、绑定accpet监听套接字
    • 5、连接指定的端点
    • 6、服务器接收连接

点击查看代码

1、Asio概述

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

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

普通的网络编程,通常是指使用传统的系统调用和同步阻塞的方式进行网络通信,可以看看代码:
点击进入
其中的accept、recv、listen等函数默认是同步/阻塞的。

下面将使用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
森明帮大于黑虎帮
哔哩哔哩

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com