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_INE
    uint16_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 的返回值, 即 fd
    serv_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, // 0
    const struct sockaddr *to,//接收方的 IP 和 port
    socklen_t tolen //上一个参数的大小
);

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

ssize_t recvfrom(
    int s, //套接字
    void *buf, //接受的内容存放的位置的首地址
    size_t len, //接收的大小
    int flags, //0
    struct sockaddr *from, //提供空间即可, 存放发送方的 IP 和 PORT
    socklen_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 struct
    in_addr imr_address;//本地的 IP 地址, 填固定的宏 INADDR_ANY 即可
    int imr_ifindex; //网卡编号( 物理硬件地址) , 可以用物理硬件 ID 函数:                                                     if_nametoindex("ens33"); 其中 ens33 是网卡的
名字, 通过名字获取编号
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据面试题 —— 数据库

目录 关系型数据库与非关系型数据库的区别数据库三范式MySQL中 drop、delete、truncate的区别MySQL中 char和 varchar 的区别MySQL中inner join、left join、right join以及full join的区别MySQL中 having 和 where 的区别count(*)、count(1)、count(列名)的区别MySQL中视图和表…

【C++】-类模板-002

1创建类模板 &#xff08;1&#xff09;新建工程 &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09;模板运行结果 2【UI】设计器 &#xff08;1&#xff09;跳转到【UI】设计器 &#xff08;2&#xff09;添加…

神经网络中的归一化

我们今天介绍一下神经网络中的归一化方法~ 之前学到的机器学习中的归一化是将数据缩放到特定范围内&#xff0c;以消除不同特征之间的量纲和取值范围差异。通过将原始数据缩放到一个特定的范围内&#xff0c;比如[0,1]或者[-1,1]&#xff0c;来消除不同特征之间的量纲和取值范围…

Ti雷达CFG阅读技巧

Ti雷达CFG阅读技巧 使用TI雷达测量数据前&#xff0c;需要考虑不同的设计参数之间的区别&#xff0c;虽然Ti雷达的说明文档非常清晰&#xff0c;直接查询mmwave_sdk_user_guide文档就可以了&#xff0c;但是用的多了&#xff0c;参数都知道可能是什么含义&#xff0c;来回查询…

Springboot集成Mybatispuls操作mysql数据库-04

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

商务分析方法与工具(七):Python的趣味快捷-异常处理结构

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

布局全球内容生态,酷开科技Coolita AIOS以硬核品质亮相

当前&#xff0c;全球产业链供应链格局持续重构&#xff0c;成为影响中国对外经济发展的重要因素。2024年4月15至5月5日&#xff0c;历史久、规模大、层次高&#xff0c;作为中国外贸风向标的第135届中国进出口商品交易会&#xff08;即广交会&#xff09;在美丽的广州隆重举行…

matlab打开文件对话框

在使用matlab GUI制作时&#xff0c;为了便于用户交互使用&#xff0c;经常设置文件打开对话框&#xff0c;让用户根据实际需要选择打开的文件。下面以打开一张图片为例&#xff0c;matlab代码如下&#xff1a; [temp_filepath,temp_filename]uigetfile(*.jpg,请选择要打开的图…

探秘Tailwind CSS:前端开发的加速器(TailwindCSS让CSS编写更简洁)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Tailwind CSS 📒📝 快速体验📝 深入学习⚓️ 相关链接 ⚓️📖 介绍 📖 在这个快速迭代的互联网时代,前端开发效率和设计质量的双重要求,使得开发者们不断寻求更高效的工具和方法。今天,我们要介绍的是一个能够极大…

如何在Python中调用系统命令或执行外部程序?详细教程来了!

基本原理 在Python中执行程序或调用系统命令是一项非常实用的技能&#xff0c;这允许Python脚本与操作系统进行交互&#xff0c;执行各种外部程序。Python提供了多种方法来实现这一功能&#xff0c;包括os.system(), subprocess模块等。 示例代码 示例1&#xff1a;使用os.s…

LLM生态下爬虫程序的现状与未来

最近出现一批与LLM有关的新的爬虫框架&#xff0c;一类是为LLM提供内容抓取解析的&#xff0c;比如 Jina Reader 和 FireCrawl &#xff0c;可以将抓取的网页解析为markdown这样的对LLM友好的内容&#xff0c;例如markdown&#xff0c;这类本质上还是传统的爬虫解决方案。还有一…

[C++] const 成员函数

标题&#xff1a;[C] this指针 & const 成员函数 水墨不写bug 正文开始&#xff1a; 目录 &#xff08;一&#xff09;Cpp的面向对象编程 &#xff08;二&#xff09;this指针 &#xff08;三&#xff09;const修饰的成员函数 在正式讲解const修饰成员函数之前&#x…

在做题中学习(55):一维前缀和模板

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 题目解释&#xff1a; 注意&#xff1a;下标从1开始的。 l 和 r就是对这n个整数去取一个区间&#xff0c;例如示例一&#xff1a; (1,2) 区间 就是算出1 2 4 中 1&#xff0c;2下标对应值的和&#xff0c;12 3 同理,(2,3) …

vscode正则匹配技巧

写正则表达式 下面是匹配加粗的单词或空格 \*\*[a-zA-Z\s]*\*\*vscode提取加粗的内容 altenter&#xff0c;再ctrlC复制选中的内容出来

前端 | iframe框架标签应用(三)| 点击指定部分,进行外部页面搜索,内置iframe返回搜索结果

文章目录 &#x1f4da;实现效果&#x1f4da;模块实现解析 &#x1f4da;实现效果 点击单词列表内的任意单词↓ 弹出对应单词的搜狗翻译搜索结果&#xff0c;点击关闭按钮关闭界面。 &#x1f4da;模块实现解析 在列表框搜索功能的基础上加一个click触发效果就好了&#xf…

网络安全在数字时代的重要性:以近期网络安全事件为镜

在当今这个信息化爆炸的时代&#xff0c;互联网如同一张无形的网&#xff0c;将我们的生活、工作、学习紧密相连。然而&#xff0c;这张网在带来便捷的同时&#xff0c;也暗藏着无数的安全隐患。近年来&#xff0c;网络安全事件频发&#xff0c;从个人隐私泄露到企业数据被盗&a…

网站未部署证书有何影响,如何解决?

如果您的网站没有ssl证书会有以下风险 1 浏览器标记为不安全 未安装证书的网站在访问时会有不安全的提示弹窗或者在网址栏直接显示不安全 2 影响企业信誉 当用户访问网站时看到不安全提示&#xff0c;会对网站的真实性和安全性产生怀疑&#xff0c;不敢轻易与该企业合作&…

【NodeMCU实时天气时钟温湿度项目 2】WIFI模式设置及连接

第一专题内容&#xff0c;请参考 【NodeMCU实时天气时钟温湿度项目 1】连接点亮SPI-TFT屏幕和UI布局设计-CSDN博客 第三专题内容&#xff0c;请参考 【NodeMCU实时天气时钟温湿度项目 3】连接SHT30传感器&#xff0c;获取并显示当前环境温湿度数据&#…

初探 JUC 并发编程:独占锁 ReentrantLock 底层源码解析

本篇是关于 JUC 并发包中独占锁 ReentrantLock 底层源码的解析&#xff0c;在阅读之前需要对 AQS 抽象队列有基本的了解。 文章目录 1.1 类图结构1.2 获取锁1&#xff09;void lock() 方法2&#xff09;void lockInterruptibly() 方法3&#xff09;boolean tryLock() 方法4&am…

(✌)粤嵌—2024/5/10—删除链表的倒数第 N 个结点

代码实现&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* removeNthFromEnd(struct ListNode *head, int n) {if (head NULL || n 0) {return head;}int i n;struct ListNode …
最新文章