C++网络编程之套接字基础

news2024/10/11 10:22:21

概述

        在网络编程中,套接字(Socket)是一种用于进程间通信的接口。套接字是操作系统提供的一种抽象层,它允许不同计算机之间的进程通过网络进行通信。套接字实际上并不神秘,简单来说,套接字是连接网络中不同主机上应用程序的桥梁,通过套接字,应用程序可以发送和接收数据。

        套接字有多种类型,最常见的两种是:流式套接字和数据报套接字。

        流式套接字:基于TCP协议,提供面向连接的、可靠的数据传输服务。数据在传输过程中会被组织成无边界的字节流,并按照发送顺序到达接收端。

        数据报套接字:基于UDP协议,提供无连接的、不可靠的数据传输服务。每个数据报都是独立的,系统不保证数据报的顺序,也不保证一定到达。

基本步骤

        无论是客户端还是服务器,使用套接字进行网络编程通常包括以下几个主要步骤。

        1、创建套接字。创建一个新的套接字,用于网络通信。创建时,需要指定地址族(IPv4、IPv6等)、套接字类型(TCP、UDP等)。

        2、绑定地址。仅对服务器有效,将套接字绑定到一个特定的IP地址和端口,以便客户端可以连接到它。

        3、监听连接。可选,仅对TCP服务器有效,服务器开始监听指定端口上的连接请求。

        4、接受连接。仅对TCP服务器有效,服务器接受来自客户端的连接请求。这将返回一个新的套接字,用于与该客户端的网络通信。

        5、主动连接。仅对TCP客户端有效,客户端主动连接到服务器。主动连接时,需要指定服务器的IP地址和端口。

        6、发送/接收数据。客户端与服务器通过套接字发送和接收数据,数据的内容和格式由应用层指定。

        7、关闭套接字。完成网络通信后,关闭套接字,释放相应的资源。

        为了更加形象地理解TCP网络通信中客户端和服务器的具体行为,可以参考下面的时序图。

接口介绍

        C++并没有内置的套接字编程库,但可以使用C语言中的套接字API来实现网络通信。这些API通常是POSIX标准的一部分,在<sys/socket.h>头文件中定义。常用的套接字编程接口如下。

        1、socket函数:用于创建一个新的套接字。

int socket(int domain, int type, int protocol);

        domain:指定协议族,取值一般为AF_INET(对于IPv4)、AF_INET6(对于IPv6)。

        type:指定套接字类型,取值一般为SOCK_STREAM(对于TCP)、SOCK_DGRAM(对于UDP)。

        protocol:通常设置为0,表示选择默认协议。

        返回值:成功时返回一个套接字描述符,失败时返回-1。

        2、bind函数:用于将一个套接字绑定到一个特定的地址和端口。这个函数是网络编程中的一个重要步骤,特别是在服务器编程中,因为它允许服务器监听特定的IP地址和端口。

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

        sockfd:套接字描述符。

        addr:指向sockaddr结构体的指针,包含地址信息。sockaddr是一个通用的、最小化的结构体,其定义如下。其中,sa_family是一个整数,表示地址族,常见的值为AF_INET(对于IPv4)、AF_INET6(对于IPv6)。对于IPv4地址,通常使用sockaddr_in结构体。对于IPv6地址,通常使用sockaddr_in6结构体。

struct sockaddr
{
    sa_family_t sa_family;
    char sa_data[14];
};

struct sockaddr_in
{
    sa_family_t    sin_family;  // 地址族,通常是AF_INET
    in_port_t      sin_port;    // 端口号,网络字节序
    struct in_addr sin_addr;
    char           sin_zero[8];
};

struct in_addr
{
    uint32_t s_addr;          // IPv4地址,网络字节序
};

struct sockaddr_in6
{
    sa_family_t     sin6_family;   // 地址族,通常是AF_INET6
    in_port_t       sin6_port;     // 端口号,网络字节序
    uint32_t        sin6_flowinfo;
    struct in6_addr sin6_addr;
    uint32_t        sin6_scope_id;
};

struct in6_addr
{
    unsigned char s6_addr[16];      // 16字节的IPv6地址
};

        addrlen:addr的长度,通常是sizeof(sockaddr_in) 或 sizeof(sockaddr_in6)。

        返回值:成功时返回0,失败时返回-1。

        3、listen函数:用于将套接字设置为监听状态,准备接受连接请求。该函数仅对TCP服务器有效。

int listen(int sockfd, int backlog);

        sockfd:套接字描述符。

        backlog:未完成连接队列的最大长度,主要作用是控制服务器在处理大量并发连接时的行为。当服务器收到大量的连接请求时,内核会将这些请求放入队列中。如果队列已满,新的连接请求可能会被拒绝或丢弃。如果 backlog设置得太小,可能会导致一些连接请求被拒绝。如果backlog设置得太大,可能会占用更多的系统资源,但可以更好地处理突发的大量连接请求。

        返回值:成功时返回0,失败时返回-1。

        4、accep函数:用于从监听套接字上接受一个连接请求。当客户端尝试连接到服务器时,服务器会使用accept函数来接收这个连接,并创建一个新的套接字描述符,以便与该客户端进行通信。该函数仅对TCP服务器有效。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

        sockfd:监听套接字描述符。

        addr:指向sockaddr结构体的指针,用于存储客户端的地址信息。

        addrlen:指向addr长度的指针。

        返回值:成功时返回新的连接套接字描述符,失败时返回-1。

        5、connect函数:用于发起一个连接请求到指定的服务器,以便与服务器建立连接。该函数仅对TCP客户端有效。

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

        sockfd:套接字描述符。

        addr:指向sockaddr结构体的指针,包含目标地址信息。

        addrlen:addr 的长度。

        返回值:成功时返回0,失败时返回-1。

        6、send函数:用于向已连接的套接字发送数据,通常用于TCP套接字。

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

        sockfd:套接字描述符。

        buf:指向要发送的数据缓冲区的指针。

        len:要发送的数据长度。

        flags:控制发送操作的标志,常用标志的取值如下。

        (1)0:默认值,无特殊行为。

        (2)MSG_OOB:发送带外数据。

        (3)MSG_DONTROUTE:不要路由,直接发送到本地网络。

        (4)MSG_NOSIGNAL:当对端关闭时,防止SIGPIPE信号。

        返回值:成功时返回实际发送的字节数,失败时返回-1。

        7、recv函数:用于从已连接的套接字接收数据,通常用于TCP套接字。

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

        sockfd:套接字描述符。

        buf:指向接收数据缓冲区的指针。

        len:缓冲区的最大长度。

        flags:控制接收操作的标志,常用标志的取值如下。

        (1)0:默认值,无特殊行为。

        (2)MSG_OOB:接收带外数据。

        (3)MSG_PEEK:查看数据,而不从输入队列中移除。

        (4)MSG_WAITALL:等待直到接收了指定数量的字节或连接关闭(可能被信号中断)。

        返回值:成功时返回实际接收的字节数,失败时返回 -1。

        8、sendto函数:用于向指定的目标地址发送数据,通常用于UDP套接字。

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, 
    const struct sockaddr *dest_addr, socklen_t addrlen);

        sockfd:套接字描述符。

        buf:指向要发送的数据缓冲区的指针。

        len:要发送的数据长度。

        flags:控制发送操作的标志。

        dest_addr:指向目标地址的sockaddr结构体。

        addrlen:dest_addr的长度。

        返回值:成功时返回实际发送的字节数,失败时返回-1。

        9、recvfrom函数:用于从一个无连接的套接字接收数据,并且可以获取发送方的地址信息,通常用于UDP套接字。

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, 
    struct sockaddr *src_addr, socklen_t *addrlen);

        sockfd:套接字描述符。

        buf:指向接收数据缓冲区的指针。

        len:缓冲区的最大长度。

        flags:控制接收操作的标志。

        src_addr:指向发送方地址的sockaddr结构体。

        addrlen:src_addr的长度。

        返回值:成功时返回实际接收的字节数,失败时返回-1。

        10、close函数:用于关闭文件描述符,包括套接字。在调用close函数之前,确保所有未发送的数据都已经发送完毕。如果还有待发送的数据,这些数据可能会被丢弃。对于接收端,确保已经读取了所有来自对端的数据。一旦调用了close函数,就无法再从该套接字接收数据。好的编程习惯是:一旦不再需要套接字,就立即调用close函数,以释放相关的系统资源。

int close(int sockfd);

        sockfd:套接字描述符。

        返回值:成功时返回0,失败时返回-1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2204672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【射频通信电子线路第七讲】射频收发信机结构及具体的实例应用

一、射频收发器 &#xff08;一&#xff09;功能与需求 &#xff08;1&#xff09;频率变换&#xff1a;调制解调、混频、不同于信息变换 电平变换&#xff1a;放大、衰减 干扰抑制&#xff1a;滤波、抵消 &#xff08;2&#xff09;发射出的信号&#xff1a;高频、一定功…

【动态规划】状态 dp

动态规划步骤&#xff1a; 状态表示。所谓状态表示就是 dp 表里的值表示什么含义&#xff0c;那么状态表示怎么找呢&#xff1f; a. 题目要求 b. 经验&#xff08;以某一个位置为结尾 / 起点&#xff09; 题目要求 c. 分析问题的过程中发现重复子问题状态转移方程。dp[ i ] 等…

<Project-8.1 pdf2tx-MM> Python Flask 用浏览器翻译PDF内容 2个翻译引擎 繁简中文结果 从P8更改

更新 Project Name&#xff1a;pdf2tx (P6) Date: 5oct.24 Function: 在浏览器中翻译PDF文件 Code:https://blog.csdn.net/davenian/article/details/142723144 升级 Project Name: pdf2tx-mm (P8) 7oct.24 加入多线程&#xff0c;分页OCR识别&#xff0c;提高性能与速度 使…

美发店管理革新:SpringBoot系统的应用

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理美发门店管理系统的相关信息成为必然。开发…

3D生成基础模型来了!只需5秒,高质量3D资产规模化生成!南洋理工等重磅开源3DTopia-XL

文章链接&#xff1a;https://arxiv.org/pdf/2409.12957 项目链接&#xff1a;https://3dtopia.github.io/3DTopia-XL/ 今天AI生成未来和大家分享的是南洋理工、北大、上海AI Lab和港中文联合发布的3D PBR资产生成最新工作3DTopia-XL。通过基于高效且表达力强的3D表示方法Pri…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor &#xff08;官方链接 https://microsoft.github.io/monaco-editor/&#xff09;是一个由微软开发的功能强大的在线代码编辑器&#xff0c;被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

【linux 多进程并发】0201 Linux进程fork内存空间,父子进程变量内存地址居然是一样的

0201 Linux进程fork方式详解 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章…

学习记录:js算法(五十七):二叉树中所有距离为 K 的结点

文章目录 二叉树中所有距离为 K 的结点思路一思路二 二叉树中所有距离为 K 的结点 给定一个二叉树&#xff08;具有根结点 root&#xff09;&#xff0c; 一个目标结点 target &#xff0c;和一个整数值 k &#xff0c;返回到目标结点 target 距离为 k 的所有结点的值的数组。&…

matlab002

新建工程test001 例如&#xff1a; 脚本&#xff08;Script&#xff09; 概念 脚本是一系列按顺序执行的 MATLAB 命令的集合。它就像是一个记录了你在命令行中输入的一系列指令的文件。用途 适用于简单的任务&#xff0c;例如数据处理、可视化等一次性的操作。例如&#xff0c…

重学SpringBoot3-集成Redis(四)之Redisson

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;四&#xff09;之Redisson 1. 添加 Redisson 依赖2. 配置 Redisson 客户端3. 使用 Redisson 实现分布式锁4. 调用分布式锁5. 为什…

Java 获取热搜并生成图片

效果图如下&#xff1a; 第一步获取热搜 public List<String> getHotNews4(Integer size) {if (size < 0 || StringUtils.isEmpty(size)) {return null;}try {//set 转listreturn new ArrayList<>(getHotNews(size));} catch (Exception e) {logger.error(&qu…

如何基于审批实现文件外发管控,阻断数据违规外流?

FTP可以说是实际中企业运用最广泛的文件传输方式&#xff0c;很多企业不仅内部传输文件使用FTP&#xff0c;在与外部合作伙伴协作时&#xff0c;也多采用FTP进行文件的外发和收取。例如半导体行业&#xff0c;默认的都是使用FTP进行文件外发&#xff0c;这时候&#xff0c;替换…

卷积神经网络细节问题及知识点

一、Batch Normalization Batch Normalization&#xff08;BN&#xff0c;批归一化&#xff09; 是深度学习中的一种技术&#xff0c;主要用于加速神经网络的训练过程&#xff0c;同时提高网络的稳定性和收敛速度。它通过对每一层的输出进行归一化&#xff0c;减少梯度消失和梯…

本地部署Docsify生成文档网站并实现公网环境远程访问

文章目录 前言1. 本地部署Docsify2. 使用Docsify搭建个人博客3. 安装Cpolar内网穿透工具4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows环境本地部署 Docsify 这款以 markdown 为中心的文档编辑器&#xff0c;并即时生成您的文档博客网站&#xff0c;结合…

ubuntu22.04 安装wine9.0 全网首发

wine官网推荐安装方式&#xff1a;https://gitlab.winehq.org/wine/wine/-/wikis/zh_CN/Debian-Ubuntu 博主按照这种方式是失败的&#xff0c;虽然开启了“低调上网”&#xff0c;貌似代理对于终端不起作用&#xff0c;后面会介绍替代方案&#xff0c;一样完美。 一、官网的安…

Pycharm里设置关于designer.exe以及pyuic5.exe的外部工具

文章目录 1.Pycharm与Pyuic5介绍(1)Pycharm(2)Pyuic5 2.Pycharm里设置外部工具(1)切换到外部工具(2)designer创建外部工具(3)pyuic5创建外部工具(4)使用designer和pyuic5 3.本章总结 1.Pycharm与Pyuic5介绍 (1)Pycharm Pycharm是专门用于python编程语言的编辑软件&#xff0c;…

QT的核心机制 对话框资源

案例 1、键盘按下w&#xff0c;s&#xff0c;a&#xff0c;d键分别为标签向上&#xff0c;下&#xff0c;左&#xff0c;右移动 鼠标按下获取本地坐标&#xff0c;全局坐标 鼠标双击获取本地坐标&#xff0c;全局坐标 鼠标移动获取本地坐标&#xff0c;全局坐标 让鼠标跟踪…

C语言 ——— oj题:有效的括号

目录 题目要求 代码实现 题目要求 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个…

【靶点Talk】为什么联合用药喜欢用VEGF+VEGFR?

血管生成对肿瘤发生、发展的重要影响的发现&#xff0c;使肿管生成变为肿瘤研究的热点之一。今天给大家带来VEGF、VEGFR相关介绍&#xff0c;更多靶点科普视频请关注义翘神州B站和知乎官方账号。 1、VEGFR的“简历” VEGFR包括VEGFR-1、VEGFR-2和VEGFR-3。VEGFR-2可与多种VEGF…

leetcode hot100_part03_滑动窗口

滑动窗口是有一个基本的模版的&#xff0c;不要自己想当然哦~ 滑动窗口算法思想&#xff08;附经典例题&#xff09;_滑动窗口的思想-CSDN博客 滑动窗口也叫同向双指针&#xff1b;可以先看一下灵山视频&#xff1a;滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili 3.无重复字…