【Linux网络 (二)】套接字编程

news/2024/11/24 9:17:01/

Linux: 网络

  • 一、前言
  • 二、端口号 (port)
    • 1)port、套接字概念
    • 2)端口号 vs 进程id
    • 3)端口号和进程关系
  • 三、认识TCP/Udp协议
    • 1)连接性解释
    • 2)可靠性解释
    • 3)面向数据报/字节流解释
  • 四、网络字节序
  • 五、struct sockaddr类型介绍
  • 六、TCP 通信API
    • 1)socket()解释
    • 2) bind()解释
      • 2.1 setsockopt()函数
      • 2.2 服务端`struct sockaddr`结构体填充样式
    • 3)listen()解释
    • 4)accept()解释
    • 5)connect()解释
    • 6)tcp读写
    • 7)Udp通信API

一、前言

 本篇文章会介绍端口号、网络字节序等网络编程中的基本概念,以及udp/tcp套接字编程API。

二、端口号 (port)

1)port、套接字概念

网络通信的本质不同主机上的两个进程进行间通信,并且两进程会看到同一块资源——网络并且我们用ip是用于表示互联网中不同主机的地址;端口号(port)这是用于标识一台主机上的不同进程。所以ip + port既可以用于标识互联网中的唯一进程,我们也将ip + port称为套接字!!

2)端口号 vs 进程id

 端口号用于标识同一台主机上进程的唯一性,但进程id作用同样如此。那为啥在网络中不复用进程id知识,而是引入端口号呢?

  1. 其一是为了让网络模块和系统模块进行接藕,减低两者间的耦合度!
  2. 其二是并不是所有的进程都有通信的需求。而port专用于网络通信!

3)端口号和进程关系

  1. 一个进程可以绑定多个端口号,但一个端口号不能被多个进程绑定!

三、认识TCP/Udp协议

 我们先对TCP和UDP有一个大概的认识,在后面再详细讲解它的协议内容。

TCP协议:

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

UDP协议:

  • 传输层协议
  • 没有连接
  • 不可靠传输
  • 面向数据报

1)连接性解释

 tcp在通信前需要先建立连接,也就是大名鼎鼎的3次握手,2次挥手;而UDP通信什么都不用提前做。我们可以将tcp通信比喻成打电话时,我们在通信前需要先获得对方同意,对方同意接你电话;将tcp想象为寄快递,我只需要知道对方地址即可!

2)可靠性解释

 tcp是可靠,Udp不可靠。那生活中我们采用tcp就可以了,为啥需要Udp?

 原因在于tcp的可靠性是有代价的(数据丢包,超时重传、数据粘包等问题需要处理),而udp认为只要将即数据从传输层发给网络层就认为数据发生成功了,所以tcp通信比udp慢。并且可靠、不可靠描述的是两种协议的特点,并没有谁好谁坏。在当前网络环境中,数据丢包的概率极小。
 针对不同的场景,可以选择不同的通信方式。如果对数据可靠性要求高的场景,我们可以采用tcp,比如支付过程。反之采用udp协议,在满足需求的前提下,大大提高通信速度。比如直播,偶尔出现数据丢包,对我们影响不大就可以采用udp协议!

3)面向数据报/字节流解释

 面向数据报是指报文之间是有边界的,应用层交给UDP多长的报文,UDP原样发送,既不拆分也不合并。读端每次只读取一个完整报文!
 面向字节流是指数据向流水一样,是没有明显边界的。对于读端,读端并不关系写端写了多少次,读到的数据是否完整,而是尽可能将数据全部读取上来交给上层!

四、网络字节序

 内存中的多字节数据相对于内存地址有大端和小端之分。这也意味着数据从A主机经网络发给B主机,B主机收到的数据可能是反的。所以网络规定,所有发送到网络中的数据必须是大端!!先发出的数据是低地址,后发出的数据是高地址。

 但人为大小端数据转换非常复杂,所以系统也提高了一系列转换接口:
在这里插入图片描述

五、struct sockaddr类型介绍

网络通信时,socket有很多类型,主要有如下3种:

  1. 域间套接字Unix socket:主要用于本主机内部通信。域间套接字通过套接字文件来进行通信,进程可以通过打开这个文件来进行读写操作,从而实现通信。
  2. 网络socket:通过ip + port来进行网络通信。
  3. 原始socket:原始套接字绕过传输层,直接通过网络层进行通信。主要用于编写一些网络工具。

网络中套接字种类很多,理论而言,我们要为每一种套接字设计对应的一套接口。但这无疑加重程序员的负担,为了统一所有套接字API,网络通用地址类型struct sockaddr类型诞生!!
在这里插入图片描述

六、TCP 通信API

在这里插入图片描述

1)socket()解释

 socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符。应用程序可以像读写文件一样用read/write在网络上收发数据。如果socket()调用出错则返回-1。

domain(协议家族):即socket()函数采用的网络协议种类,在网络通信中一般选择AF_INET
type(套接字类型):对于tcp而言,面向字节流,选择SOCK_STREAM
protocol(协议):通常前面两个参数就明确的通信协议种类,所以一般填0

2) bind()解释

 bind 函数用于将一个套接字(socket)与特定的IP地址和端口号关联起来。(将参数sockfd和myaddr绑定在一起, 使sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号)

  1. 对于服务端ip和port是固定的,但我们一般只绑定port,而ip选择任意地址。原因在于一台机器上可能存在多张网卡,即一台主机从多个ip(网卡)读取数据都应该交给上层指定端口(port)   但对于客户端而言,虽然也需要绑定ip+port,但不需要显示绑定。原因在于客户端程序很多,如果直接由用户显示绑定,可能会导致某些时刻端口号冲突,导致一些程序无法正常启动!所以客户端在首次发送信息时,OS会自动绑定。
  2. bind调用时,如果短时间内重复调用会失败,这和tcp断开连接时会进入TIME_WAIT状态有关。我们只需要通过地址复用即可,具体做法如下:
    int opt = 1; setsockopt(_listensockfd, SOL_SOCKET, SO_REUSEADDR| SO_REUSEPORT, &opt, sizeof(opt)); // 地址复用

2.1 setsockopt()函数

int setsockopt(int sockfd, int level, int option_name, const void *option_value, socklen_t option_len);
  • socockfd:要设置选项的套接字描述符。
  • level:指定了选项所在的协议层级。套接字层选SOL_SOCKET
  • option_name:设置的选项的名称。主要有两选项:SO_REUSEADDR允许地址和端口的复用;SO_REUSEPORT与 SO_REUSEADDR 类似,但提供了更细粒度的控制。
  • option_value需要设置的选项值。
  • option_len:option_value指针指向的变量长度。

2.2 服务端struct sockaddr结构体填充样式

在这里插入图片描述

3)listen()解释

 tcp在通信前需要先建立连接,但服务端如何得知客户端发起了请求开始建立连接呢?所以我们需要通过listen()函数将套接字设置为监听状态!!

 listen()声明sockfd处于监听状态, 并且最多允许有backlog个客户端处于连接等待状态, 如果接收到更多的连接请求就忽略。listen()成功返回0,失败返回-1;

4)accept()解释

 三次握手完成后, 服务器调用accept()接受连接,并返回一个新的文件描述符! 如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来。   addr是一个传出参数,accept()返回时传出客户端的地址和端口号;如果给addr 参数传NULL,表示不关心客户端的地址。

如何理解返回一个新的文件描述符:

 通过listen()将套接字设置为监听状态,我们可以帮监听套接字理解为饭店外进行拉客的工作人员!他的工作只是将客人拉到字节饭店即可,并不真正提高服务;而是重新叫一名服务员进行招待后,出去重新拉客。
 所以监听套接字就好比拉客的工作人员,他只是用于监听等待客户端发起连接。  而返回的新的文件描述符才是真正和客户端进行交互的。后续可客户端和服务端进行网络通信,都是通过新的文件描述符来进行!!

5)connect()解释

 客户端需要调用connect()连接服务器;connect和bind的参数形式一致, 区别在于bind的参数是自己的地址, 而connect的参数是对方的地址;!!
 connect()成功返回0,出错返回-1。

6)tcp读写

 tcp客户端和服务端通信和文件一样,通过read、write进行!

7)Udp通信API

 UDp只需要将建socket文件文件描述符(本质是创建文件细节,将网卡文件打开),然后绑定ip+port即可通信。

 UDP通信消息收发通过recvfrom、sendto完成!
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/1549497.html

相关文章

【Isaac Sim】配置 Nucleus 本地服务器

Omniverse 提供了本地(局域)服务器 Nucleus,可以将资产上传到该服务器,Nucleus 能够高效地存储和管理大量三维模型和其他资产,确保用户可以轻松访问这些资源。它还支持多用户环境下的实时协作,使得不同地理…

【贪心算法】绿洲之旅:最少次数补给探索

文章目录 问题背景解决思路贪心算法的优势实现步骤详解 问题背景 假设一位旅行者需要穿越一片沙漠,起点到终点的距离为 D 公里,旅行者初始携带了 W 升水,每前进一公里需要消耗一升水。在穿越过程中,沿途会经过 N 个补给站&#x…

人工智能(AI)与机器学习(ML)基础知识

目录 1. 人工智能与机器学习的核心概念 什么是人工智能(AI)? 什么是机器学习(ML)? 什么是深度学习(DL)? 2. 机器学习的三大类型 (1)监督式学…

uiautomator案例

test下新建类 public class ButtonClickTest {private UiDevice device;Beforepublic void setUp() {// 初始化 UiDevice 实例device UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());try {device.executeShellCommand("am start -n com.yy.test/.…

JAVA部署到生产环境(服务器 全)

将Java应用部署到生产环境是一个复杂且需要细心规划的过程,主要包括代码准备、构建、测试、部署和监控等步骤。以下是一个完整的流程: 1. 准备阶段 1.1 确认需求与目标 确认生产环境的部署目标,例如性能要求、可用性、容灾能力等。制定部署…

leetcode刷题记录(四十二)——101. 对称二叉树

(一)问题描述 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/symmetric-tree/description/给你…

二进制 分析工具:Radare2、r2frida、Binutils、file、string、as、nm、ldd、objdump、readelf、strip

1、二进制 分析工具 工欲善其事,必先利其器,在二进制安全的学习中,​使用工具尤为重要。遇到一个不熟悉的文件时, 首先要确定 "这是什么类型的文件",回答这个问题的首要原则是,绝不要根据文件的扩…

【青牛科技】 GC1288:散热风扇领域中 LA6588 / 三洋的理想替代者

在散热风扇的驱动芯片领域,芯麦 GC1288 以其独特的优势脱颖而出,成为替代 LA6588 / 三洋芯片的优质之选。它为散热风扇带来了更卓越的性能和更可靠的运行保障,在行业内引起了广泛关注。 一、GC1288 的特点 (一)优秀的…