网络编程(套接字)

目录

一、套接字

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.pswp.cn/diannao/91344.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91344.shtml

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

相关文章

R语言安装包

# 在安装过程中指定源地址 install.packages("RCurl", repos "https://mirrors.tuna.tsinghua.edu.cn/CRAN/") # 查看当前镜像 options()$repos # 设置为中科大镜像 options("repos" c(CRAN"https://mirrors.ustc.edu.cn/CRAN/")…

微服务引擎 MSE 及云原生 API 网关 2025 年 5 月产品动态

点击此处&#xff0c;了解微服务引擎 MSE 产品详情。

性能测试过程中监控linux服务器资源情况

文章目录1. cpu使用情况&#xff08;1&#xff09;性能瓶颈类型CPU密集型瓶颈​​I/O或等待瓶颈​&#xff08;2&#xff09;资源分配与竞争​资源争用分析​虚拟化环境资源分配​&#xff08;3&#xff09;系统稳定性与异常​​异常波动与毛刺​​过热降频影响​&#xff08;4…

使用defineExpose暴露子组件的属性和方法、页面生命周期onLoad和onReady的使用

欢迎来到我的UniApp技术专栏&#xff01;&#x1f389; 在这里&#xff0c;我将与大家分享关于UniApp开发的实用技巧、最佳实践和项目经验。 专栏特色&#xff1a; &#x1f4f1; 跨平台开发一站式解决方案 &#x1f680; 从入门到精通的完整学习路径 &#x1f4a1; 实战项目经…

新手必看!VSCodePyCharm 配置 OpenCV 超详细教程(支持 Python 和 C++ 双语言)

新手必看&#xff01;VSCode&PyCharm 配置 OpenCV 超详细教程&#xff08;支持 Python 和 C 双语言&#xff09; 适用对象&#xff1a;初学者&#xff0c;希望在 VSCode 与 PyCharm 两款常用 IDE 中&#xff0c;学会配置并使用 OpenCV&#xff0c;分别实现 Python 与 C 环境…

PyTorch深度学习框架入门案例实战

PyTorch深度学习框架详解与实战 1. PyTorch简介与环境配置 1.1 安装与导入 # 基础导入 import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset import numpy as np import…

Spring Boot - Spring Boot 集成 MyBatis 分页实现 手写 SQL 分页

一、准备阶段 1、依赖引入 pom.xml <properties>...<postgresql.verison>42.5.6</postgresql.verison><mybatis.version>3.0.1</mybatis.version> </properties><dependencies>...<!-- postgresql 驱动 --><dependency>…

李宏毅《生成式人工智能导论》 | 第9讲 AI Agent

文章目录大模型未来趋势&#xff1a;以大型语言模型打造的AgentAI Agent运行的可能原理有记忆的ChatGPT大模型未来趋势&#xff1a;以大型语言模型打造的Agent 人类需要做多步骤的复杂任务&#xff0c;AI可以做到这件事吗&#xff1f; 如果可以我们将其称为AI Agent&#xff…

OCR 与 AI 图像识别:协同共生的智能双引擎

OCR 擅长提取图像中的文字信息&#xff0c;但面对复杂背景、扭曲角度的图片时&#xff0c;容易受干扰&#xff1b;AI 图像识别能解析图像场景、物体形态&#xff0c;却难以精准捕捉文字细节 —— 两者结合才能释放最大价值。比如在票据处理中&#xff0c;AI 图像识别先定位票据…

C# 按照主题的订阅 按照类型的订阅

安装TinyPubSub库&#xff0c;按照 主题发布订阅using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Form…

当执行shell时,出现未预期的符号 `$‘\r‘‘ 附近有语法错误

1.当执行shell时&#xff0c;出现未预期的符号 $‘\r’’ 附近有语法错误 解决&#xff1a; linux下解决&#xff1a; 方案一&#xff1a; Linux下打开shell文件&#xff0c;用vi/vim命令打开脚本文件&#xff0c;输入“:set fileformatunix”&#xff0c;回车&#xff0c;保存…

合作共赢|华望系统科技受邀出席杭州市基础软件和工业软件产业技术联盟成立大会

大会现场&#xff08;图源官方&#xff09;2025年7月11日&#xff0c;在杭州市经济和信息化局&#xff08;杭州市数字经济局&#xff09;的指导下&#xff0c;杭州市基础软件与工业软件产业技术联盟成立大会暨工业软件生态共性云平台发布仪式在西电杭州研究院圆满举行。会上&am…

7.17 滑动窗口

lc523.同余定理两个注意点同余定理&#xff1a;余数相同的两个数&#xff0c;做差可被整除。--前缀和hash存mod&#xff0c;不可以用set&#xff0c;因为要保证len大于等于2&#xff0c;所以要存idx映射&#xff01;&#xff01;还有对于全选和全不选的两个边界&#xff0c;下标…

算法与前端的可访问性

引言 可访问性&#xff08;Accessibility, a11y&#xff09;是现代 Web 开发的核心&#xff0c;确保所有用户&#xff0c;包括残障人士&#xff0c;都能无障碍地使用应用。算法在优化前端性能的同时&#xff0c;也能通过高效的数据处理和交互逻辑提升可访问性体验。例如&#x…

使用token调用Spring OAuth2 Resource Server接口错误 insufficient_scope

1、场景 最近照着《Spring Security实战》学习&#xff0c;学到第18章&#xff0c;使用Keycloak作为授权服务器&#xff0c;使用 org.springframework.boot:spring-boot-starter-oauth2-resource-server 实现资源服务器&#xff0c;调用资源服务器的接口返回403&#xff0c;具…

4. 观察者模式

目录一、现实应用场景二、初步实现2.1 实现方案12.2 实现方案2三、观察者模式3.1 应用场景3.2 详解3.3 实现3.4 设计类图四、实现五、更多一、现实应用场景 教师的手机号改变之后要通知给所有学生如果有一个学生没有通知到位就会产生遗漏如何自动完成 二、初步实现 2.1 实现…

es 启动中的一些记录

完整修复流程 bash # 1. 创建用户主目录(如果需要) mkdir -p /home/es8 chown es8:es8 /home/es8# 2. 变更 Elasticsearch 目录所有权 chown -R es8:es8 /data/es/elasticsearch-8.17.2/# 3. 调整目录和文件权限 chmod -R 755 /data/es/elasticsearch-8.17.2/ chmod 644 /d…

区块链之拜占庭容错算法——Practical Byzantine Fault Tolerance(PBFT)

实用拜占庭容错算法&#xff08;PBFT&#xff09;是由 Barbara Liskov 和 Miguel Castro 于 90 年代末提出的一种共识算法。原论文链接如下&#xff1a; http://pmg.csail.mit.edu/papers/osdi99.pdf pBFT 被设计为在异步&#xff08;响应请求的时间没有上限&#xff09;系统…

从电子管到CPU

在线verilog转电路图 简单门电路 https://logic.ly/demo/ 数学基础 普通逻辑 与自然语言关系紧密, 亚里士多德三段论,‌‌穆勒五法 , 语言, 语义,概念,定义,辩论, 诈骗 等, 是文科类的逻辑。 离散数学 不连续数学 数理逻辑 命题逻辑与谓词逻辑, 与数学推理关系紧密, 它…

Javase-8.数组的练习

1.查找数组中指定元素(二分查找)以升序数组为例, 二分查找的思路是先取中间位置的元素, 然后使用待查找元素与数组中间元素进行比较&#xff1a; 如果相等&#xff0c;即找到了返回该元素在数组中的下标 如果小于&#xff0c;以类似方式到数组左半侧查找 如果大于&#xff0c;以…