Linux 操作系统TCP、UDP

1、TCP服务器编写流程

头文件:

#include <sys/socket.h>

1.1 创建套接字

函数原型:

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

参数:

        domain: 网域
               AF_INET : IPv4
               AF_INET6 : IPv6
               AF_UNIX : 本地通讯

type:选择传输协议  tcp/udp

                SOCK_STREAM ; tcp
                SOCK_DGRAM : udp

protocol: 基本废弃, 一般赋 0
返回值: 成功返回描述网络套接字 sockfd, 失败返回-1
举例: 创建描述网络的套接字:

int sfd = socket(AF_INET,SOCK_STREAM,0);

1.2 绑定

头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

作用:绑定一个端口和IP地址,使套接口与指定的端口号和IP地址相关联

函数原型:

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

参数:

        sockfd 为前面 socket 的返回值, 描述网络的套接字
        my_addr:封装 ip 地址和端口号

struct sockaddr //一般很少用
{unsigned short int sa_family; // AF_INET。char sa_data[14]; //IP 和端口
};
struct sockaddr_in //常用的结构体
{unsigned short int sin_family; //AF_INEuint16_t sin_port; //使用的 port 编号struct in_addr sin_addr; // IP 地址unsigned char sin_zero[8]; //未使用
};

端口:10000-65535之间随意选

转化:

uint32_t htonl(uint32_t hostlong);//本函数将一个 32 位数从主机字节顺序转换成无符号长整型网络字节顺序
uint16_t htons(uint16_t hostshort);//将一个无符号短整型的主机数值转换为网络字节顺序
uint32_t ntohl(uint32_t netlong);//将一个无符号长整形数从网络字节顺序转换为主机字节顺序。
uint16_t ntohs(uint16_t netshort);//将一个 16 位数由网络字节顺序转换为主机字节顺序。

IP的填写方式:

struct in_addr
{uint32_t s_addr; //=inet_addr("192.168.1.22");
};

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

举例:

#define PORT 33333
#define IP "192.168.110.123"
struct sockaddr_in ser_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(PORT);
ser_addr.sin_addr.s_addr = inet_addr(IP);
inet_aton(“192.168.1.22”,&ser_addr.sin_addr);
bind(sfd,(struct sockaddr)&ser_addr,sizeof(ser_addr));

1.3 监听

作用:设置允许的最大连接数(瞬间处理的阀值),listen函数。

使用服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端哟连接请求,端口就会接受这个链接。

函数原型:

int listen(int sockfd, int backlog);

参数:

        sockfd 为前面 socket 的返回值, sfd
        backlog 指定同时能处理的最大连接要求, 通常为 10 或者 5。 最大值可设至 128( 不是最多可以连接 128个客户端, 是一个瞬时处理的阈值)
返回值: 成功则返回 0, 失败返回-1

1.4 等待客户端连接

函数原型:

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

参数:

        sockfd 为前面 socket 的返回值, 即 sfd
        addr: 提供空间, 用于接受客户端的 ip 地址和端口号
        addrlen: 第二个参数大小

返回值:

        返回新的套接字描述符, 专门用于与建立的客户端通信
        失败-1;

举例:

struct sockaddr_in cli_addr = {0};
socklen_t len = sizeof(cli_addr);
int cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len);

1.5 读写函数

可以使用read和write函数进行。

写函数

函数原型;

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

参数:

        s: 通信套接字
        buf: 要发送的数据缓冲区
        len: 数据长度
        flags: 一般赋 0 .阻塞

返回值:成功返回真正发送的数据长度,失败-1.

读函数

函数原型:

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

参数:

        s: 通信的套接字
        buf:存放接收数据的缓冲区
        len: 数据长度
        flags: 一般赋 0 .阻塞

返回值:成功返回真正接收的数据长度,失败-1.

2 TCP客户端编写流程

2.1 创建套接字

头文件:

#include <sys/socket.h>

函数原型:

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

参数:

        domain: 网域
                AF_INET : IPv4
                AF_INET6 : IPv6
        type: 选择传输协议 tcp /udp
                SOCK_STREAM ; tcp
                SOCK_DGRAM : udp
        protocol: 基本废弃, 一般赋 0

返回值:成功返回套接字fd,失败返回-1

2.2 连接

函数原型:

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

参数:

    sockfd 为前面 socket 的返回值, 即 fdserv_addr 为结构体指针变量, 存储着远程服务器的 IP 与端口号信息。addrlen 表示结构体变量的长度

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

举例:

    int fd = socket(AF_INET,SOCK_STREAM,0);#define PORT 33333#define IP "192.168.110.123"struct sockaddr_in ser_addr;ser_addr.sin_family = AF_INET;ser_addr.sin_port = htons(PORT);ser_addr.sin_addr.s_addr = inet_addr(IP);connect(fd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));

TCP 问题: 当服务器结束之后, 再次运行会出现 bind 错误(地址被占用)
解决办法:

      int sfd = socket(AF_INET,SOCK_STREAM,0);


创建套接字之后, 用:

int val = 1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
setsockopt(sfd,SOL_SOCKET,SO_REUSEPORT,&val,sizeof(val));

3.UDP

特点:非面向连接,不可靠传输,传输速率高

分别有:

单播  --  一对一                广播  --  一对多          组播  --  多对多

3.1 单播

        UDP不像TCP。无需在连接状态下交换数据,因此基于UDP的接收方和发送发也无需经过连接过程。也就是说,不必调用listen()和accept()函数。UDP中有创建套接字的过程和数据交换的过程。不管是接收方还是发送方都只需要1个套接字。

3.1.1 创建套接字
头文件:

#include <sys/socket.h>

函数原型:

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

参数:

        domain: 网域
        AF_INET : IPv4
        AF_INET6 : IPv6
        type: 选择传输协议 tcp /udp
        SOCK_STREAM ; tcp
        SOCK_DGRAM : udp
        protocol: 基本废弃, 一般赋 0
返回值: 成功返回套接字 fd, 失败返回

3.1.2 bind:绑定自己的IP和端口

发送方:socket   同接收方

函数原型:

ssize_t sendto( int s, //套接字const void *buf, //要发送的数据的首地址size_t len, //数据的大小int flags, // 0const struct sockaddr *to,//接收方的 IP 和 portsocklen_t tolen //上一个参数的大小
);

返回值:成功返回真正发送的数据长度,失败-1

ssize_t recvfrom(int s, //套接字void *buf, //接受的内容存放的位置的首地址size_t len, //接收的大小int flags, //0struct sockaddr *from, //提供空间即可, 存放发送方的 IP 和 PORTsocklen_t *fromlen//上一个参数的大小, 但是填指针
);

返回值:成功返回真正接收的数据长度, 失败-1

3.2 广播

udp具有广播功能,即一个发送方,多个接收方;

广播:处于局部网络中的所有设备都可以接收消息

广播的地址:网络号不变,主机号为255 

socket 创建的 UDP 套接字支持组播和广播, 但是想要使用广播, 必须用 setsockopt 设置广播的功能。

接收方:
        1》 创建套接字 socket UDP
        2》 绑定 IP 和 PORT IP 填 INADDR_ANY
        3》 recvfrom 接收

发送方:

        1》 创建套接字 socket UDP
        2》 开启广播功能: setsockopt

开启广播功能函数

int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t optlen);

函数功能:设置套接字的选项

参数:

sockfd创建的套接字

        level--选项所在的级别:
        想让套接字有广播功能, 就必须把 level 设置为 SOL_SOCKET
                SOL_SOCKET -- 广播功能所在的级别
        optname--选项所在的名称:
                SO_BROADCAST (广播功能)
        optval: 整数的地址
                int num = 1;//开启功能 &num
                0--失能(关闭此功能,系统默认关闭)
                1--使能(开启此功能)
        optlen: optval 的大小 //sizeof(num);

举例:

int a = 1;
setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&a,sizeof(int));

sendto 发送


3.3 多播

对一组特定的主机发送消息 比如: 直播, 多播(D 类), IP 地址分为: 224.0.0.0~239.255.255.255

1》 创建套接字 socket UDP
 

 int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

函数功能: 设置套接字的选项
参数:
        sockfd: socket 创建的套接字
        level: 级别
        SOL_SOCKET : 广播级别
        IPPROTO_IP : 组播级别

        optname: 选项由 level 决定, level 选的是 IPPROTO_IP, optname 有两种选择
        IP_ADD_MEMBERSHIP 加入组播
        IP_MULTICAST_IF 创建组播
        optval: 设置参数 由 optname 决定
        当 optname 为:
                IP_ADD_MEMBERSHIP( 加入组播) , optval 是 struct ip_mreqn 这个结构体
                IP_MULTICAST_IF ( 创建组播) , optval 也是 struct ip_mreqn 这个结构体

struct ip_mreqn
{struct in_addr imr_multiaddr;//多播组的地址 224.0.0.0-239.255.255.255 structin_addr imr_address;//本地的 IP 地址, 填固定的宏 INADDR_ANY 即可int imr_ifindex; //网卡编号( 物理硬件地址) , 可以用物理硬件 ID 函数:                                                     if_nametoindex("ens33"); 其中 ens33 是网卡的
名字, 通过名字获取编号
};

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十五届蓝桥杯省赛大学B组(c++)

很幸运拿了辽宁赛区的省一,进入6月1号的国赛啦... 这篇文章主要对第十五届省赛大学B组(C)进行一次完整的复盘,这次省赛2道填空题6道编程题: A.握手问题 把握手情景看成矩阵: 粉色部分是7个不能互相捂手的情况 由于每个人只能和其他人捂手, 所以黑色情况是不算的 1和2握手2和…

Vue+OpenLayers7入门到实战:OpenLayers解析通过fetch请求的GeoJson格式数据,并叠加要素文字标注,以行政区划边界为例

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上通过fetch请求geojson数据,然后通过OpenLayers解析为Feature要素叠加到图层上,并且通过动态设置标注方式显示要素属性为文字标注。 本章还是以行政区划边界为例,这个…

大模型LLM之SFT微调总结

一. SFT微调是什么 在大模型的加持下现有的语义理解系统的效果有一个质的飞跃&#xff1b;相对于之前的有监督的Pre-Train模型&#xff1b;大模型在某些特定的任务中碾压式的超过传统nlp效果&#xff1b;由于常见的大模型参数量巨大&#xff1b;在实际工作中很难直接对大模型训…

游戏陪玩平台app小程序H5源码交付游戏陪玩接单软件游戏陪玩源码 陪玩小程序陪玩工作室运营模式陪玩管理系统游戏陪玩工作室怎么做

提供陪玩平台源码&#xff0c;陪玩系统源码&#xff0c;陪玩app源码&#xff0c;团队各部门配备齐全&#xff0c;分工明确&#xff0c;及时对接开发进度&#xff0c;保证开发效率 一、陪玩平台源码的功能介绍 1、派单大厅:陪玩系统源码的派单大厅内支持用户通过语音连麦的方式…

Vue.js-----vue组件

能够说出vue生命周期能够掌握axios的使用能够了解$refs, $nextTick作用能够完成购物车案例 Vue 生命周期讲解 1.钩子函数 目标&#xff1a;Vue 框架内置函数&#xff0c;随着组件的生命周期阶段&#xff0c;自动执行 作用: 特定的时间点&#xff0c;执行特定的操作场景: 组…

硬性清空缓存的方法

前端发布代码后&#xff0c;我们是需要刷新页面再验证的。有时候仅仅f5 或者ctrlshiftdelete快捷键仍然有历史缓存&#xff0c;这时可以通过下面的方法硬性清空缓存。 以谷歌浏览器为例&#xff0c;打开f12&#xff0c;右键点击刷新按钮&#xff0c;选择【清空缓存并硬性加载】…

Windows只能安装在GPT磁盘上

转换磁盘分区形式 步骤1. 先按照正常流程使用Windows系统安装光盘或系统U盘引导计算机。 步骤2. 在Windows安装程序中点击“开始安装”&#xff0c;然后按ShiftF10打开命令提示符。 步骤3. 依次输入以下命令&#xff0c;并在每一行命令后按一次Enter键执行。 步骤4. 等待转换…

C++ | Leetcode C++题解之第78题子集

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> t;vector<vector<int>> ans;void dfs(int cur, vector<int>& nums) {if (cur nums.size()) {ans.push_back(t);return;}t.push_back(nums[cur]);dfs(cur 1, nums);t.po…

自动驾驶学习2-毫米波雷达

1、简介 1.1 频段 毫米波波长短、频段宽,比较容易实现窄波束,雷达分辨率高,不易受干扰。波长介于1~10mm的电磁波,频率大致范围是30GHz~300GHz 毫米波雷达是测量被测物体相对距离、相对速度、方位的高精度传感器。 车载毫米波雷达主要有24GHz、60GHz、77GHz、79GHz四个频段。 …

深度学习基础之《TensorFlow框架(17)—卷积神经网络》

一、卷积神经网络介绍 1、背景 随着人工智能需求的提升&#xff0c;我们想要做复杂的图像识别&#xff0c;做自然语言处理&#xff0c;做语义分析翻译等等&#xff0c;多层神经网络的简单叠加显然力不从心 2、卷积神经网络与传统多层神经网络对比 &#xff08;1&#xff09;传…

实战 | 18行代码轻松实现人脸实时检测【附完整代码与源码详解】Opencv、人脸检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【图像识别】Swin Transformer

一、引言 论文&#xff1a; Swin Transformer: Hierarchical Vision Transformer using Shifted Windows 作者&#xff1a; Microsoft Research Asia 代码&#xff1a; Swin Transformer 特点&#xff1a; 提出滑动窗口自注意力 (Shifted Window based Self-Attention) 解决Vi…

【3D基础】坐标转换——地理坐标投影到平面

汤国安版GIS原理第二章重点 1.常见投影方式 https://download.csdn.net/blog/column/9283203/83387473 Web Mercator投影&#xff08;Web Mercator Projection&#xff09;&#xff1a; 优点&#xff1a; 在 Web 地图中广泛使用&#xff0c;易于显示并与在线地图服务集成。在…

java.net.SocketInputStream.socketRead0 卡死导致 tomcat 线程池打满的问题

0 TL;DR; 问题与原因&#xff1a;某些特定条件下 java.net.SocketInputStream.socketRead0 方法会卡死&#xff0c;导致运行线程一直被占用导致泄露采用的方案&#xff1a;使用监控线程异步监控卡死事件&#xff0c;如果发生直接关闭网络连接释放链接以及对应的线程 1. 问题 …

Burp Suite 抓包,浏览器提示有软件正在阻止Firefox安全地连接到此网站

问题现象 有软件正在阻止Firefox安全地连接到此网站 解决办法 没有安装证书&#xff0c;在浏览器里面安装bp的证书就可以了 参考&#xff1a;教程合集 《H01-启动和激活Burp.docx》——第5步

WhisperCLI-本地部署语音识别系统;Mis开源LLM推理平台;Dokploy-开源版Vercel;Mem-大规模知识图谱

1. Whisper-cli&#xff1a;可本地部署的开源语音识别系统 近日&#xff0c;Ruff的开发团队发布了一款名为Whisper cpp cli的全新语音识别系统&#xff0c;该系统已在GitHub Repo上开源。这是一款完全自主研发的语音转文字系统&#xff0c;基于Whisper技术构建。Ruff团队一直以…

Istio基础知识

一、什么是Istio Istio 提供⼀种简单的⽅式来为已部署的服务建⽴⽹络&#xff0c;该⽹络具有 负载均衡、服务间认证、监控等功能&#xff0c;只需要对服务的代码进⾏⼀点或不需要做任何改动。想要让服务⽀持 Istio&#xff0c;只需要在您的环境中部署⼀个特殊的 sidecar 代 理&…

netsh命令

netsh是本地或远程计算机Windows 2000网络组件的命令行和脚本实用程序。为了存档或配置其他服务器&#xff0c;netsh实用程序也可将配置脚本保存在文本文件中。netsh实用程序是一个外壳&#xff0c;通过附加的“netsh帮助DLL”可支持多个Windows 2000组件。 有两种方式可以运行…

从 Servlet 到 DispatcherServlet(SpringMvc 容器的创建)

DispatcherServlet 的继承体系 SpringMvc 是一个具有 Spring 容器&#xff08;ApplicationContext&#xff09;的 Servlet。其中&#xff0c;HttpServlet 属于 JDK 的内容&#xff0c;从 HttpServletBean 开始&#xff0c;便属于 Spring 体系中的内容。 HttpServletBean&…

unity制作app(5)--发送数据给数据库

这个之前做过&#xff0c;先不做照片的。下一节再做带照片的。 第一步 收集数据 1.先做一个AppModel结构体&#xff0c;这个结构体需要单做的。 using System; using System.Collections.Generic; using System.Linq; using System.Text; //using Assets.Model; public clas…