【Linux】探索网络编程:TCP/UDP协议解析与Socket应用实例

文章目录

  • 前言:
  • 1. 预备知识
    • 1.1 理解源IP地址和目的IP地址
    • 1.2 认识端口号
    • 1.3 理解"端口号"和"进程ID"
    • 1.4 理解源端口号和目的端口号
    • 1.5 认识TCP协议
    • 1.6 认识UDP协议
    • 1.6 TCP vs UDP 可靠性
    • 1.7 网络字节序
  • 2. socket 编程接口
    • 2.1 socket 常见API
    • 2.2 sockaddr结构
  • 3. 简单的UDP网络程序
    • 3.1 UDP实现简易聊天室:
  • 总结:

前言:

在现代信息技术飞速发展的今天,网络通信已经成为我们日常生活和工作中不可或缺的一部分。无论是通过电子邮件、社交媒体还是在线会议,网络通信都扮演着至关重要的角色。而在这背后,是复杂的网络协议和编程技术支撑着这一切的运行。本文旨在深入探讨网络编程的基础知识,特别是UDP和TCP这两种常用的传输层协议,以及它们在socket编程中的应用。通过本文,读者将能够理解源IP地址、目的IP地址、端口号等概念,并学习如何使用socket编程接口来创建网络应用程序。此外,本文还将介绍网络字节序的概念,以及如何通过转换函数确保网络程序的可移植性。最后,通过一个简单的UDP网络程序实例,我们将展示如何实现一个回声服务器和简易聊天室,让读者对网络编程有更直观的认识。

1. 预备知识

1.1 理解源IP地址和目的IP地址

在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址。

思考: 我们光有IP地址就可以完成通信了嘛? 想象一下发qq消息的例子, 有了IP地址能够把消息发送到对方的机器上,但是还需要有一个其他的标识来区分出, 这个数据要给哪个程序进行解析。

1.2 认识端口号

  1. 我们上网,无非两种动作:a. 把远端的数据拉取到本地 b. 把我的数据发送到远端
  2. 大部分的网络通信行为,都是用户触发的。计算机中,谁表示用户呢?进程!(客户端服务,服务端服务)
  3. 把数据发送到目标主机,不是目的,是手段。正真的目的,是把数据交给这个主机上的某一个服务(进程)(服务必须具有唯一的标识:端口号)
  4. 网络通信的本质,其实是进程帮我们进行网络通信,无论是对于C还是S
  5. IP(唯一的一台主机)+ port(该主机的唯一的一个进程) = 互联网中唯一的一个进程
  6. client -> server: client进程 -> server进程
    client进程 = client ip + client port = client是互联网中唯一的一个进程
    server进程 = server ip + server port = server是互联网中唯一的一个进程
    唯一的找到彼此(src ip, src port; dst ip, dst port)(socket通信)

结论: 网络通信的本质:其实就是进程间通信!
进程间通信:看到公共的资源(网络)

1.3 理解"端口号"和"进程ID"

我们之前在学习系统编程的时候, 学习了 pid 表示唯一一个进程; 此处我们的端口号也是唯一表示一个进程. 那么这两者之间是怎样的关系?

  • PID 是操作系统用来标识一个进程的唯一编号。
  • 端口号 是网络通信中用来标识主机上特定服务的数字。

它们之间没有直接关系,PID用于操作系统内部管理,而端口号用于网络通信。另外, 一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定。

1.4 理解源端口号和目的端口号

传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 就是在描述 “数据是谁发的, 要发给谁”;

1.5 认识TCP协议

此处我们先对TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识; 后面我们再详细讨论TCP的一些细节问题.

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

1.6 认识UDP协议

此处我们也是对UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识; 后面再详细讨论.

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

1.6 TCP vs UDP 可靠性

TCP 要保证可靠性,就需要做更多的工作——TCP协议一定更复杂——接口会更多一些。
UDP 协议一定更简单。

1.7 网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
  • 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
  • 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;

在这里插入图片描述
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。
在这里插入图片描述

  • 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回 ;
  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

2. socket 编程接口

2.1 socket 常见API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器) 
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,
 socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,   socklen_t addrlen);

2.2 sockaddr结构

socket编程,是有不同种类的,有的是专门用来进行本地通信的(unix socket),有的是用来专门跨网络通信的(inet socket),有的是用来进行网络管理的(raw socket)。

统一接口 -> C语言写的 -> 统一类型 -> struct sockaddr

在这里插入图片描述

3. 简单的UDP网络程序

bind: socket = ip + port; 文件信息和网络信息给关联起来

   #include <sys/types.h>          /* See NOTES */
   #include <sys/socket.h>

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

填充信息:
在这里插入图片描述

sin_addr —— 16位地址类型: AF_INET、 32位IP地址
sin_port —— 16位端口号
sin_zero —— 8字节填充

在这里插入图片描述
如何理解 “192.168.1.2” <==> 4字节IP地址之间互相转换

// 4字节 转 字符串
struct IP
{
	uint8_t p1;
	uint8_t p2;
	uint8_t p3;
	uint8_t p4;
}

struct IP *temp = (struct IP*)&ipaddr;
to_string(temp->p1) + "." + to_string(temp->p2) + ...
// 字符串 转 4字节
struct IP temp;
temp.p1 = stoi(substr("."));
uint32_t ipint = (int)temp;

127.0.0.1 : 本地环回
在这里插入图片描述

./udpserver 127.0.0.1 8888

127.0.0.1 : 本地环回,可以实现本地通信,常用于进行代码测试
在这里插入图片描述
recvfrom(接收消息)

// 接收信息
   ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                    struct sockaddr *src_addr, socklen_t *addrlen);
   		// buf: 输出型缓冲区
   		// len: 期望长度
   		// 返回值: 实际读到的长度
   		// src_addr: 输出型参数(ip 与 port)
   		// addrlen: 输出型参数

有人给你发了消息,你想不想知道谁给你发的? 为什么? 因为我还要给别人回消息
你通过什么信息,只到只到对方是谁? socket 对方的 IP 和 port!

sendto(发送消息)

// 发送信息
   ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                  const struct sockaddr *dest_addr, socklen_t addrlen);

使用公网ip,我们的服务器,无法直接bind公网ip(云服务器不允许),也严重不推荐,bind公网ip,或者任何一个确定的ip。
在这里插入图片描述

实现一个回声服务器:
在这里插入图片描述
在这里插入图片描述
终端输出也是一个文件,不同的终端窗口是不同的文件。
在这里插入图片描述

3.1 UDP实现简易聊天室:

gitee:https://gitee.com/q-haodong/test_-linux/tree/master/20240702_udp_echo_sever
在这里插入图片描述
在这里插入图片描述

总结:

本文从网络通信的基本概念出发,逐步深入到TCP和UDP协议的细节,并探讨了它们在socket编程中的应用。通过预备知识的介绍,我们理解了源IP地址、目的IP地址、端口号等在网络通信中的重要性。同时,我们也学习了网络字节序的概念,以及如何通过特定的函数进行主机字节序和网络字节序之间的转换,以确保程序的兼容性和可移植性。在socket编程接口部分,我们介绍了创建socket文件描述符、绑定端口号、监听socket、接收请求、建立连接等常见API的使用。最后,通过实现一个UDP回声服务器和简易聊天室的示例,我们展示了UDP协议在实际网络编程中的应用。通过本文的学习,读者不仅能够掌握网络编程的基础知识,还能够获得实际编程的经验,为进一步深入学习和探索网络编程打下坚实的基础。

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

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

相关文章

为了SourceInsight从Linux回到Windows

什么是SourceInsight 现在上网搜索这个软件&#xff0c;大多数说他是一个代码阅读软件&#xff1b;但是在官方的说法里面&#xff0c;这是一款支持多语言的编辑器。大概长这样&#xff1a; 看起来十分老旧是吧&#xff0c;但是他其实他已经是第四代了哈哈哈。其实这个软件是我…

LeetCode 全排列

思路&#xff1a;这是一道暴力搜索问题&#xff0c;我们需要列出答案的所有可能组合。 题目给我们一个数组&#xff0c;我们很容易想到的做法是将数组中的元素进行排列&#xff0c;如何区分已选中和未选中的元素&#xff0c;容易想到的是建立一个标记数组&#xff0c;已经选中的…

开发电商ERP系统需要接入哪些平台API?

跟随全渠道发展趋势&#xff0c;很多实体商家开设电商店铺&#xff0c;为消费者提供便捷的购物体验&#xff0c;增强消费者的满意度&#xff0c;同时也提升了企业自身的市场竞争力。为了满足商家业务拓展需求&#xff0c;很多原本主要服务于实体商贸企业的ERP服务商&#xff0c…

vim快捷键 提高工作效率

目录 1. :set nu 显示行号 :set nonu 取消显示行号 2. End 快速移动光标到行尾 3. Home 快速移动光标到行首 4. 10G 快速移动光标到第10行 5. G 快速到文件的底部 6. 1G 快速到第一行 &#xff08;gg&#xff09; 7. …

[Mysql] 的基础知识和sql 语句.教你速成(下)——数据库的约束篇

目录 前言 约束 一.我们为什么需要约束 二.常见的约束类型 NOT NULL 约束 UNIQUE 约束 DEFAULT 约束 PRIMARY KEY FOREIGN KEY CHECK约束 原因&#xff1a; 结尾 前言 距离上篇的更新已经快两周了,这个时候大伙都已经考完了吧!现在更新多少有点马后炮,但是没办法呀…

Kubernetes基于helm安装 harbor

Kubernetes基于helm安装 harbor 之前harbor的安装都是借助docker完成一键安装部署&#xff0c;安装完成之后harbor组件均运行到一台机器上面&#xff0c;本文实践harbor在k8s环境中的部署。 准备工作 根据harbor官方要求&#xff1a; Kubernetes cluster 1.20Helm v3.2.0 …

精准定位推广盲点?Xinstall数据监测让每一分投入都见成效!

在这个数字化时代&#xff0c;App的推广早已不再是简单的“上线即成功”。面对激烈的市场竞争和日益挑剔的用户&#xff0c;如何精准监测推广数据&#xff0c;优化营销策略&#xff0c;成为了每个开发者与营销人员不得不面对的挑战。而在这个关键时刻&#xff0c;Xinstall作为一…

shark云原生-日志体系-filebeat高级配置(适用于生产)

文章目录 1. filebeat.inputs 静态日志收集器2. filebeat.autodiscover 自动发现2.1. autodiscover 和 inputs2.2. 如何配置1.2.1. Providers 提供者1.2.2. Providers kubernetes templates1.2.3. 基于提示&#xff08;hints&#xff09;的自动发现支持的 **hints**的完整列表&…

2024 AI工程师世界博览会

6月24日至6月27日在旧金山举行的 AI 工程师世界博览会是AI 从业者和爱好者的首要活动之一。本次年度会议展示了人工智能技术的最新进展&#xff0c;并提供了对行业趋势的宝贵见解。 模型不是壁垒 大型语言模型&#xff08;LLMs&#xff09;的快速发展是会议的中心主题。OpenAI…

element-ui Tree之懒加载叶子节点强制设置父级半选效果

效果&#xff1a; 前言&#xff1a; 我们是先只展示一级的&#xff0c;二级的数据是通过点击之后通过服务器获取数据&#xff0c;并不是全量数据直接一起返回回来的。 问题&#xff1a; 当你设置了默认选中的子节点&#xff0c;但是由于刚进入页面此时tree中数据暂是没有这个…

深入解读:如何解决微调扩散模型时微调数据集和训练数据集之间的差距过大问题?

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;在微调扩散模型的时候经常会遇到微调数据集和训练数据集之间的差距过大&#xff0c;导致训练效果很差。在图像生成任务中并不明显&#xff0c;但是在视频生成任务中这个问题非常突出。这篇博客深入解读如何…

代码随想录算法训练营第69天:图论7[1]

代码随想录算法训练营第69天&#xff1a;图论7 109. 冗余连接II 卡码网题目链接&#xff08;ACM模式&#xff09;(opens new window) 题目描述 有向树指满足以下条件的有向图。该树只有一个根节点&#xff0c;所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节…

5分钟读懂GPS-RTK实时动态技术,建议收藏!

由于”智慧工地“理念的兴起和发展&#xff0c;目前越来越多的企业将信息技术手段融合于施工现场安全管理&#xff0c;构建智能化的安全监管模式。基于此&#xff0c;蓝牙LORA融合定位技术、UWB超宽带定位技术、GPS-RTK定位技术等信息技术也越来越频繁出现在大众视野。然而&…

单片机软件架构连载(4)-结构体

枚举、指针、结构体&#xff0c;我愿称为C语言"三板斧"。 用人话来讲&#xff0c;几乎所有c语言高阶编程&#xff0c;都离不开这这3个知识点的应用。 今天站在实际产品常用的角度&#xff0c;给大家讲一下结构体。 1.结构体概念 结构体可以用来构建更复杂的数据结…

Diffusion模型的微调和引导

留意后续更新&#xff0c;欢迎关注微信公众号&#xff1a;组学之心 Diffusion模型的微调和引导 微调&#xff08;fine-tuning&#xff09;&#xff1a; 从一个已经训练过的模型开始训练&#xff0c;我们就可以从一个学会如何“去噪”的模型开始训练&#xff0c;相对于随机初始…

c++:动态内存变量

典型的C面向对象编程 元素 (1)头文件hpp中类的定义 (2)源文件cpp中类的实现&#xff08;构造函数、析构函数、方法&#xff09; (3)主程序 案例 (1)用C来编程“人一天的生活” (2)“人”的属性&#xff1a;name、age、male (3)“人”的方法&#xff1a;eat、work(coding/shop…

【免费可视化工具】助力风电行业智能化管理

在绿色能源日益成为全球共识的今天&#xff0c;风电作为清洁能源的重要组成部分&#xff0c;正以前所未有的速度发展。然而&#xff0c;随着风电场规模的扩大和数量的增加&#xff0c;如何高效、直观地管理和监控风电资源成为了一个亟待解决的问题。 而山海鲸可视化这款免费可…

汉光联创HGLM2200N黑白激光多功能一体机加粉及常见问题处理

基本参数&#xff1a; 机器型号&#xff1a;HGLM2200N 产品名称&#xff1a;A4黑白激光多功能一体机 基础功能&#xff1a;打印、扫描、复印 打印速度&#xff1a;22页/分钟 纸张输入容量&#xff1a;150-249页 单面支持纸张尺寸&#xff1a;A4、A5、A6 产品尺寸&#x…

功能详解-电商接口丨电商API

随着电商平台各类机制日益成熟&#xff0c;电商接口逐渐被大家所熟知&#xff0c;淘宝、天猫、京东、拼多多、抖店、快手、小红书这些都是主流的电商平台&#xff0c;为了提升电商管理系统的效率&#xff0c;开发者可以通过电商接口将多个电商平台的数据和功能集成。 电商接…

firewalld高级配置

一、1、关于iptables的知识 IP数据包过滤系统是一种功能强大的工具&#xff0c;可用于添加、编辑和除去规则&#xff0c;这些规则是做数据包过滤决定时&#xff0c;防火墙所遵循和组成的规则。这些规则存储在专用的数据包过滤表中&#xff0c;而这些表集成在Linux内核中。在数据…