网络编程(套接字)

目录

一、套接字

1、套接字的作用

2、关于TCP和UDP协议

1. TCP协议

2. UDP协议

3. 两者的区别

2、套接字函数

1)函数 socket(创建套接字同文件描述符)

2)准备套接字用结构体

1. 套接字的结构体

2. 客户端的套接字:

3. 服务器的套接字:

3)bind(以结构体向套接字中写入 ip、port)

4)send / write(通过套接字发送数据)

5)recv / read(通过套接字接收数据)

6)fcntl(变更函数状态:阻塞/非阻塞)


一、套接字

套接字在最初只是一种IPC通讯手段,在TCP协议出现,TCP协议使用套接字进行通信,因此我们常说的套接字都是应用于网络通信,而早期只用于进程间通讯的则称为域套接字

1、套接字的作用

专门用于网络间通信的一种文件形式

该文件,包含了要交换的数据和通信双方的 ip地址和 port端口号

ip地址和 port端口号需要我们自己添加到套接字中,并且不同的协议需要使用不同类型的套接字

2、关于TCP和UDP协议

TCP协议和UDP协议的套接字就是不同类型的

1. TCP协议

TCP协议是一个可靠的,连续的,基于字节流的协议,TCP具有流量控制功能,顺序控制功能,应答重发功能,以确保在网络不拥堵的时候,所有的数据都可以正确的发送

2. UDP协议

UDP协议由于非连续性,且没有有效的应答手段,所以不可靠,很容易丢包

向前纠错技术(后来各大厂商对UDP协议的更进,添加了校验的方法)

udp协议在发送数据的时候,会选择在发送 n 个数据的时候,匹配发送 m 个校验包

比如说发送 3个数据的时候,匹配发送1个校验包

最简单的校验包 = 1#数据报 + 2#数据报 + 3#数据报

比如说:发送了 1 ,2,3 这3个数据,此时,再发送一个校验包,校验包的值是 4

很明显,在丢包率为 25% 的时候,3个包配一个校验包,就能完全避免丢包

因为4个包里面丢一个,丢了校验包完全无所谓

丢的是任意一个数据包,可以通过校验包和其他数据包,恢复出丢失的数据是多少

依此类推:如果网络波动变大,我们就需要配更多的校验包,以保证丢包率减低,恢复率提高

3. 两者的区别

TCP协议稳定性高,传输速度慢,UDP协议稳定性差,传输速度快

2、套接字函数

1)函数 socket(创建套接字同文件描述符)

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建不同类型的套接字用文件描述符
参数 domain:套接字所依赖的网络介质如果是 ipv4 就填入 AF_INET如果是 ipv6 就填入 AF_INET6如果是 域套接字 就填入 AF_LOCAL / AF_UNIX
参数 type:选择套接字的类型SCOK_STREAM:字节流套接字传输数据,连续,可靠,双向,数据量大SOCL_DGRAM:数据包套接字传输数据,不连续,不可靠,有长度要求,双向
参数 protocol:选择套接字所依赖的通信协议0:自动匹配,会根据参数 type 和参数 protocol 自动选择合适的通信协议
返回值:返回创建套接字文件描述符一般来说:AF_INET + SOCK_STREAM + 0 ,最终创建的是 TCP 协议的套接字AF_INET + SOCK_DGRAM  + 0 ,最终创建的是 UDP 协议的套接字 

        字节流的优点:允许发送无穷大的数据,会在内核中对数据做分割处理,但是由于连续发送,数据依然粘连在一起

        字节流的缺点:由于数据是粘连的,因此接收端需要花费大量的时间处理数据

        数据包的优点:数据不会粘连,发送几次数据就是几个数据包

        数据包的缺点:发送的数据大小有上限,过大的数据需要手动分批次发送,还有丢包的风险

2)准备套接字用结构体

1. 套接字的结构体
struct sockaddr_in {__kernel_sa_family_t  sin_family; /* 依赖的网络介质       */__be16        sin_port;           /* port端口号           */struct in_addr    sin_addr;       /* ip地址               */
};

        127.0.0.1 是一个本地回环地址,不会经过网卡,专门用来在无网络的情况下做本地测试,
抓包工具无法抓到这个 ip地址 的数据

2. 客户端的套接字:

写入 ip地址 的目的 是为了通过 ip地址,找到该客户端想要连接的服务器

写入 port端口号 的目的 是为了通过端口号,知道数据需要发送到服务器的哪个进程  

3. 服务器的套接字:

写入 ip地址 的目的 是过滤掉不想接收的客户端,选择想要连接的客户端

写入 port端口号 的目的 是为了让服务器知道要去哪个进程读取接收到的数据

3)bind(以结构体向套接字中写入 ip、port)

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:往套接字中写入 ip地址 和 port端口号 (该操作被称为为套接字命名)
参数 sockfd:填写 套接字用文件描述法
参数 addr:通用套接字结构体指针,需要提前准备 struct sockaddr_in 类型的结构体
参数 addrlen:参数 addr 的字节长度

4)send / write(通过套接字发送数据)

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:通过套接字,向套接字中指向的ip地址发送数据
参数 sockfd:填入 socket创建的套接字文件描述符
参数 buf:填入 要发送的数据的地址
参数 len:填入 要发送的字节的长度
参数 flag:设置函数的状态 阻塞 / 非阻塞0    :默认阻塞,发送数据给目标,目标的接收区满了,就会发送阻塞MSG_DONTWAIT:非阻塞,发送数据给目标,接收区满了,丢弃新发送的数据
=======================================================================
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
用法基本一致,IO篇也有详细介绍

5)recv / read(通过套接字接收数据)

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:通过套接字,读取套接字中ip地址所发送的数据
参数 sockfd:由socket创建的套接字文件描述符
参数 buf:将读取到的数据存入buf所指向的连续地址(所指向的数组)
参数 len:所读取数据的字节长度
参数 flags:设置函数的状态 阻塞 / 非阻塞0    :默认阻塞,没有接收到数据就阻塞MSG_DONTWAIT:非阻塞,没有读取到数据直接返回 0 
返回值:阻塞模式:返回接收到数据的字节数,若套接字损坏 返回 -1若服务器与客户端连接断开,则有阻塞函数变为非阻塞函数,并返回 0非阻塞模式:返回接收到数据的字节数,若服务器与客户端断开,返回 -1未接收到参数,则返回 0
=====================================================================
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
用法基本一致,IO篇也有详细介绍

6)fcntl(变更函数状态:阻塞/非阻塞)

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
功能:设置指定文件描述符的状态,也就是flags属性
参数 cmd:设置函数的功能 设置 flags 或 读取 flagsF_SETFL:设置 fd 文件的 flags 属性F_GETFL:获取 fd 文件的 flags 属性
不定参 ···:此处只有第一个数据是有效的仅当 cmd == F_SETFL 时,需要传一个不定参作为 flags
返回值:当 cmd == F_SETFL 时,成功返回 0 ,失败返回 -1当 cmd == F_GETFL 时,返回 flags ,失败返回 -1

使用时要注意不要变更原有的状态,因此尽可能追加flags值(若有需要替换原先的值,也可以换)

使用流程:
1、先获取 fd 原有的 flags 属性
2、对获取到的 flags 属性追加
3、将追加好的 flags 属性,设置为 fd 的 flags 属性

以标准输入流为例

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

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

相关文章

Java爬虫与正则表达式——用正则来爬取数据

APIJava帮我们写好的各种功能的Java类。这些Java类统称为API。正则表达式就是API帮我们写好的类。正则表达式例子&#xff1a; 字符类&#xff1a;[abc]&#xff1a;只能是a&#xff0c;b或c[^abc]&#xff1a;除了a&#xff0c;b&#xff0c;c之外的任何字符[a-zA-Z]&#xff…

vue-router 导航式编程 参数的设置

主要是想记录一下this.$router.push、replace、go等方法的参数如何设置。字符串路径router.push(/home)直接使用字符串&#xff08;或模板字符串&#xff09;路径&#xff0c;可跳转到相应的URL路径。对象式路径路径也可以是一个对象&#xff0c;对象里以key:value的形式表示UR…

力扣每日一题--2025.7.17

&#x1f4da; 力扣每日一题–2025.7.17 &#x1f4da; 3202. 找出有效子序列的最大长度 II&#xff08;中等&#xff09; 今天我们要解决的是力扣上的第 3202 题——找出有效子序列的最大长度 II。这道题是昨天 3201 题的扩展&#xff0c;需要我们处理更一般化的情况。 ⚠️…

多线程--单例模式and工厂模式

一.什么是设计模式设计模式好⽐象棋中的"棋谱".红⽅当头炮, ⿊⽅⻢来跳.针对红⽅的⼀些⾛法,⿊⽅应招的时候有⼀ 些固定的套路.按照套路来⾛局势就不会吃亏.软件开发中也有很多常⻅的"问题场景".针对这些问题场景,⼤佬们总结出了⼀些固定的套路.按照这 个套…

notepad++ 多行复制拼接

如何将中文一 一复制到英文后面按住 ALT ,鼠标左键拖动多行选中中文Ctrl C 复制 在英文的第一行结尾处 Ctrl v 粘贴

Redis主从复制数据同步实现原理详细介绍

文章目录一、主从复制的概念二、全量复制&#xff08;完整重同步&#xff09;三、增量复制&#xff08;部分重同步&#xff09;1. 增量复制的核心思想2. 增量复制的实现3. 复制偏移量&#xff08;replicationoffset&#xff09;4. 复制积压缓冲区&#xff08;replicationbacklo…

PHP 社区正在讨论变更许可证,预计 PHP 9.0 版本将完全生效

2025年7月15日&#xff0c;PHP社区正式提出将PHP语言和Zend Engine的许可证统一为BSD-3-Clause的提案&#xff0c;标志着这个拥有28年历史的编程语言正在经历根本性的法律框架重构。此次变更不仅涉及技术实现层面的调整&#xff0c;更折射出开源软件生态在法律合规性、商业兼容…

【React Native】Switch、Alert、Dimensions、StatusBar、Image组件

其他常用组件 swich https://reactnative.dev/docs/next/switch alert Alert React Native 如果想增加里面的按钮&#xff0c;就往这个数组里&#xff0c;按照这个格式不断的加东西就行了。但是&#xff1a; 在iOS上&#xff0c;里面多少个都有问题&#xff0c;3 个以上它…

我的开发日志:随机数小程序

文章目录前言UI设计代码前言 为什么我要设计这个程序呢&#xff1f;因为我要用&#xff0c;懒得在网上下载了&#xff0c;于是干脆写了一个。 UI设计 UI是我凹出来的&#xff0c;你们要使用&#xff0c;直接新建一个UI.ui文件&#xff0c;然后把下面的东西输进去就可以了。 …

Linux之Zabbix分布式监控篇(二)

一、前置回顾zabbix作为一个分布式监控工具&#xff0c;能帮助我们7*24*365监控硬件使用情况&#xff08;cpu,内存&#xff09;&#xff0c;以及网络流量波动&#xff0c;从而能让运维能及时排查错误zabbix由zabbix-server(10051)、zabbix-agent(10050)、zabbix-database、zabb…

远程团队任务管理模板:如何高效协作,破解远程工作痛点?

随着远程工作的兴起&#xff0c;越来越多的企业和团队开始依赖虚拟工作环境来实现日常工作任务。然而&#xff0c;远程工作虽然提供了灵活性&#xff0c;但也带来了任务管理上的挑战。如何确保团队成员在不同时间、地点之间高效协作&#xff1f;这正是远程团队任务管理模板能够…

大一暑假适合学51单片机吗?

大一暑假学 51 单片机&#xff0c;简直是老天爷赏饭吃的黄金窗口。我当时就是靠着这两个月&#xff0c;把从课本上看来的 C 语言指针、循环语句&#xff0c;变成了能让 LED 按节奏跳舞的真本事。学期里总被高数作业和英语背单词挤得没整块时间&#xff0c;焊个电路板还得算着实…

C++ 返回值优化(Return Value Optimization, RVO)

C 返回值优化&#xff08;Return Value Optimization, RVO&#xff09; 在 C 中&#xff0c;返回值优化&#xff08;RVO&#xff09; 是一种编译器优化技术&#xff0c;用于减少对象的拷贝或移动操作。当函数返回一个临时对象时&#xff0c;编译器可以将该对象直接构造在调用者…

自动化框架 Selenium 的使用

介绍 Selenium 是一个用于自动化 Web 浏览器的开源工具套件&#xff0c;主要用于 Web 应用程序测试&#xff0c;也可用于网页抓取和自动化 Web 任务。 早期的selenium RC已经被现在的webDriver所替代&#xff0c;可以简单的理解为selenium1.0webdriver构成现在的Selenium2.0。…

RAG深入了解P1:从RAG类型出发看优化点

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录引言1 RAG类型1.1 基础RAG (Naive/Standard RAG)1…

Llama 2:开放基础模型与微调聊天模型

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" Llama 2&#xff1a;开放基础模型与微调聊天模型 摘要 在本研究中&#xff0c;我们开发并发布了 Llama 2&#xff0c;一组预训练和微调的大型语言模型&#xff08;LLMs&#xff09;&#xff0c;其规模从 70 亿参…

微服务变更?自动化测试利器Parasoft SOAtest修复快、准、稳!

微服务架构凭借灵活和可扩展的优势越来越普及&#xff0c;但随之而来的变更也成了开发团队的“心头大患”。服务之间依赖复杂&#xff0c;接口改来改去&#xff0c;不仅让开发更费劲&#xff0c;还容易导致测试用例失效、测试效率下降&#xff0c;甚至埋下系统不稳的隐患。 自…

[Pytorch]深度学习-part1

一、Pytorch的安装1.1打开cmd1.2 输入nvidia-smi可以查看到CUDA Version的版本是12.7我们在安装的时候&#xff0c;需要注意&#xff0c;安装的cuda要小于等于我们电脑显示的CUDA版本1.3 &#xff08;可选&#xff09;卸载之前版本Pytorch通过上述方法&#xff0c;卸载之前安装…

day055-Dockerfile与常用指令

文章目录0. 老男孩思想-女性的第一需求1. Dockerfile1.1 Dockerfile的基本结构1.2 案例-制作小鸟飞飞镜像1.2.1 编写Dockerfile文件1.2.2 构建镜像1.2.3 启动容器1.3 Dockerfile常用指令1.4 面试题&#xff1a;Dockerfile中CMD和ENTRYPOINT的区别&#xff1f;1.5 案例-制作zrlo…

用 Ray 跨节点调用 GPU 部署 DeepSeek 大模型,实现分布式高效推理

在大模型时代&#xff0c;单节点 GPU 资源往往难以满足大模型&#xff08;如 7B/13B 参数模型&#xff09;的部署需求。借助 Ray 分布式框架&#xff0c;我们可以轻松实现跨节点 GPU 资源调度&#xff0c;让大模型在多节点间高效运行。本文将以 DeepSeek-llm-7B-Chat 模型为例&…