【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.mzph.cn/web/39815.shtml

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

相关文章

Pandas数据清洗实战:精准捕捉并优雅过滤异常值,让数据分析更可靠!

1.describe()&#xff1a;查看每一列的描述性统计量 # 导包 import numpy as np import pandas as pddf pd.DataFrame(datanp.random.randint(0,10,size(5,3)),indexlist("ABCDE"),columns["Python","NumPy","Pandas"]) dfdf.descri…

2024年7月5日 十二生肖 今日运势

小运播报&#xff1a;2024年7月5日&#xff0c;星期五&#xff0c;农历五月三十 &#xff08;甲辰年庚午月庚午日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;狗、羊、虎 需要注意&#xff1a;鸡、牛、鼠 喜神方位&#xff1a;西北方 财神方位&#xff1a;正…

联合查询(多表查询)

多表查询是对多张表的数据取笛卡尔积&#xff08;关联查询可以对关联表使用别名&#xff09; 数据准备 insert into classes(name, desc) values (计算机系2019级1班, 学习了计算机原理、C和Java语言、数据结构和算法), (中文系2019级3班,学习了中国传统文学), (自动化2019级5…

土地规划与文化遗产保护:在发展浪潮中守护历史的脉络

在这个日新月异的时代&#xff0c;城市化进程如火如荼&#xff0c;土地规划作为引导城市发展方向的关键&#xff0c;承载着平衡发展与保护的重任。在追求现代化的同时&#xff0c;保护文化遗产不仅是对过去的尊重&#xff0c;更是对未来负责。本文旨在深入探讨如何在土地规划实…

为了SourceInsight从Linux回到Windows

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

高校搭建AIGC新媒体实验室,创新新闻教育教学模式

高校作为人才培养的重要阵地&#xff0c;必须紧跟时代步伐&#xff0c;不断创新教育教学模式&#xff0c;提升跨界融合育人水平&#xff0c;通过AIGC新媒体实验室探索创新人才培养模式。AIGC新媒体实验室不仅能够高效赋能高校宣传媒体矩阵&#xff0c;也可以助力教学实践与AIGC…

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

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

记录通过Cloudflare部署属于自己的docker镜像源

引言 由于最近国内无法正常拉取docker镜像&#xff0c;然而找了几个能用的docker镜像源发现拉取回来的docker镜像不是最新的版本&#xff0c;部署到Cloudflare里Workers 和 Pages&#xff0c;拉取docker 镜像成功&#xff0c;故记录部署过程。 部署服务 登录Cloudflare后&…

C++ 智能指针内存泄漏问题

shared_ptr相互嵌套导致循环引用 代码示例 #include <iostream> #include <memory> using namespace std;class B;class A { public:std::shared_ptr<B> b_ptr;~A() { std::cout << "A destroyed\n"; } };class B { public:std::shared_pt…

数据结构 1.1 数据结构的基本概念

本章总览&#xff1a; 一.什么是数据 1.数据 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程 序识别和处理的符号的集合。数据是计算机程序加工的原料。 早期计算机只能处理纯数值的问题&#xff0c;如世界第一题计算机ENI…

转让北京文化传媒公司带营业性演出经纪许可证

影视文化传播倡导将健康的影视文化有效传播给观众&#xff0c;从而构建观众与电影制作者的良 性沟通与互动&#xff0c;是沟通电影制作者与电影受众的重要桥梁。影视文化泛指以电影&#xff0c;电视方式所进行的全部文化创造&#xff0c;即体现为电影&#xff0c;电视全部的存在…

Java-List集合堆内存溢出

Java-List集合堆内存溢出 情况一情况二对照分析对照规定堆内存 情况一 往List<Object>的集合中不断插入元素&#xff0c;集合底层的数组会不断扩容&#xff0c;从0 -> 10 -> 10 10>>1…。最终出现堆内存溢出&#xff0c;是在扩容数组大小的时候。这里的过程…

【应届应知应会】SQL常用知识点50道

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;借他一双眼&#xff0c;愿这盛世如先生所愿 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凌七七~❤ 友情提供 目录 数据库的概念 (什么是数据库) RDBMS NOSQL 数据库的分类 …

深入理解 Git `git add -p` 命令中的交互选项

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

500mA、低压差、低噪声、超快、无需旁路电容的CMOS LDO稳压器RT9013

一般描述 RT9013 SOT23-5封装的外观和丝印 RT9013 是一款高性能的 500mA LDO 稳压器&#xff0c;具有极高的 PSRR 和超低压差。非常适合具有苛刻性能和空间要求的便携式射频和无线应用。 RT9013的静态电流低至25μA&#xff0c;进一步延长了电池的使用寿命。RT9013 也适用于低…

音乐发行平台无加密开源源码

适用于唱片公司&#xff0c;用于接收物料&#xff0c;下载物料功能&#xff1a;个人或机构认证&#xff0c;上传专辑和歌曲&#xff0c;版税结算环境要求php7.4Nginx 1、导入数据库 2、/inc/conn.php里填写数据库密码等后台路径/admin&#xff08;可自行修改任意入口名称&…

【JS】过滤数组中空值——arr.filter(Boolean)

前言&#xff1a;过滤数组中的空值&#xff0c;包括 &#xff08;undefined、null、“”、0、false、NaN&#xff09; Boolean函数可以将一个值转换为布尔值&#xff0c;空值会被转换为false&#xff0c;非空值会被转换为true 方法&#xff1a; const arr [1, 2, ""…

Linux-页表如何对物理内存进行映射

1.1 页框和页帧 我们知道通过页表可以将虚拟内存映射到对应的物理内存&#xff0c;而操作系统对于物理内存的管理并不是以字节为单位的&#xff0c;而是将物理内存分为许多大小为4KB的块&#xff0c;称为页框或页帧&#xff0c;这就是为什么我们在创建共享内存是建议将大小设定…

LTSPICE仿真电路:(十九)磁珠的一些简单仿真

1.作用 简单来说就是用来滤波的&#xff0c;将高频信号转化为热量滤除掉&#xff0c;低频有用信号正常通过 2.参数 上图几个参数比较简单&#xff0c;就是字面上的意思&#xff0c;更重要的就是频率阻抗图 不同曲线代表不同型号的磁珠&#xff0c;实际上除了额定电流外&#…

基于springboot+vue+uniapp的语言课学习系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…