news 2026/4/17 0:12:10

4. 网络编程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
4. 网络编程

0. 大纲:

网络编程三要素:IP地址、端口、协议、3次握手、4次挥手;
Socket套接字与TCP开发流程:服务器端程序流程、客户端程序流程;
TCP编程:服务器端程序、客户端程序编写;

1. 网络编程三要素: IP、端口、协议

1.1 TCP协议 和 UDP协议:

TCP提供一种面向连接的、可靠的字节流服务。
① TCP是面向连接的;UDP是无连接的即发送数据前不需要建立连接;
② TCP提供可靠的服务,也就是说,通过 TCP连接传输的数据不会丢失、没有重复,并且按顺序到达;UDP没有可靠性;
③ TCP是面向字节流的,实际上是 TCP把数据看成一连串无结构的字节流;UDP是面向报文的。

1.2 TCP建立连接三次握手:

三次握手就是指建立TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。
第一次握手: 客户端向服务端发送请求,等待服务端确认;
第二次握手: 服务端收到请求后知道客户端请求建立连接,回复给客户端以确认连接请求
第三次握手: 客户端收到确认后,再次发送请求给服务端,服务端收到正确请求后,如果正确则连接建立成功,完成三次握手,随后客户端与服务端之间可以开始传输数据了。
(详述第一次握手: 建立连接时,客户端发送 syn包(syn=j)到服务器,并进入 SYN=SENT状态,等待服务器确认;(SYN:同步序列编号 Synchronize Sequence Numbers)
第二次握手: 服务器收到 syn包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN包(SYN=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV状态;
第三次握手: 客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此时包发送完毕,客户端和服务器进入 ESTABLISHED(TCP连接成功)状态,完成第三次握手;
完成三次握手,客户端与服务器开始传送数据。)(下图红线指的是三次握手建立连接)

1.3 TCP断开连接四次挥手:

四次挥手是指断开TCP链接时需要经过4次确认。TCP连接是双向,A连接B、B连接A都要断开
第一次挥手: 当主机A(可以是客户端也可以是服务端)完成数据传输后,提出停止TCP连接的请求;
第二次挥手: 主机B收到请求后对其作出响应,确认这一方向上的TCP连接将关闭;
第三次挥手: 主机B端再提出反方向的连接关闭请求;
第四次挥手: 主机A对主机B的请求进行确认,双方向的关闭结束。(黑色线指四次挥手断开链接)

2. Socket套接字 与 TCP开发流程

2.1 Socket套接字:

网络编程:也叫网络通信,Socket通信,即:通信双方都独有自己的Socket对象,数据在Socket之间通过数据报包(UDP协议)或者字节流(TCP协议)的形式进行传输。
①定义:socket(简称套接字)是进程之间通信一个工具,好比现实生活中的插座,所有的家用电器要想工作都是基于插座进行,而进程之间进行网络通信需要基于socket
②语法:socket(套接字)能实现不同主机之间的进程间通信。Python中有专门的socket类:import socket;要使用socket,则通常要使用到socket模块下的socket类创建socket对象:tcp_socket= socket.socket(socket.AF_INET, socket.SOCK_STREAM)

函数名/参数含义
socket(AddressFamily, Type)用于创建一个socket对象。其中,参数AddressFamily(地址族)可以选择AF_INET用于Internet进程间通信,实际工作中常用它; 参数Type表示套接字类型,可以是SOCK_STREAM流式套接字,主要用于TCP协议。
参数1:AddressFamily地址族。即:Ipv4 还是 Ipv6;默认值:AF_INET(Ipv4);AF_INET6(Ipv6)
参数2:Type通信方式socket类型;即TCP 还是 UDP;默认值:SOCK_STREAM(TCP);SOCK_DGRAM(UDP)

③示例:

#演示socket对象的创建importsocket#导入模块#创建socket对象tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#输出内容print(tcp_socket)#运行结果:# <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>

2.2 TCP开发流程:

服务器端程序流程、客户端程序流程图:

详述:socket()服务器端有socket,客户端也有socket;多个客户端对应一个服务器端,bind()绑定服务端的IP和端口号(以元组的形式),即服务器端指定了IP和端口;客户端connect()时根据此IP和端口连接;listen()最大监听数:允许最多有多少人等待即多个客户端同时申请的情况下,服务器端最多只能服务几个,如单线程的则服务一个,如5个则最多5个客户端连接,第6个过来需要等待连接;accept()等待监听即如果没有客户端与服务端连接则等待(如 开店老板没有顾客时等待),会返回一个元组:(元组的第一个参数是负责和客户端交互的socket, 第二个参数是客户端信息),(和客户端交互的socket 的理解:服务端socket()的socket是店主,当客户端socket()的socket来交互时,由accept()返回的元组的第一个参数和客户端交互的socket的socket与客户端的socket进行交互的,并不是由服务端socket()的socket与之交互的,因为(店主)它的职责是负责等待,真正交互的不是它);一直等到connect()连接;send()发送数据;recv()接收数据:客户端发服务端收,以及服务端发客户端收;客户端close()关闭客户端,服务端close()关闭的是与客户端交互的socket、不是socket()的socket (关闭接待完的店员,不是关店);

TCP服务器端:
TCP客户端:

代码:

server_socket.py

""" 网编案例:服务端给客户端发送消息,客户端给服务端回执信息 服务器端开发流程: 1.创建服务端socket对象 2.绑定IP和端口号 3.设置最大监听数 4.等待客户端申请建立连接 5.给客户端发送消息 6.接收客户端的信息并打印 7.释放资源 注意:客户端与服务端是通过 字节流(bytes) 的形式实现的! """#导包importsocket# 1.创建服务端socket对象:ipv4,字节流(TCP)server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2.绑定IP和端口号server_socket.bind(('127.0.0.1',8080))# 3.设置最大监听数server_socket.listen(5)# 4.等待客户端申请建立连接print(111)accept_socket,client_info=server_socket.accept()# 5.给客户端发送消息accept_socket.send(b'Welcome to Python')# 6.接收客户端的信息并打印data=accept_socket.recv(1024).decode('utf-8')print(f"服务器端收到来自{client_info}的数据:"+data)# 7.释放资源accept_socket.close()# server_socket.close() # 服务器端一般不关闭

client_socket.py

""" 网编案例:服务端给客户端发送消息,客户端给服务端回执信息 客户端开发流程: 1.创建客户端socket对象 2.连接服务器端,指定:服务器端IP、端口号 3.接收服务端的信息并打印 4.给服务器端发送消息 5.释放资源 注意:客户端与服务端是通过 字节流(bytes) 的形式实现的! """#导包importsocket# 1.创建客户端socket对象:ipv4,字节流(TCP)client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2.连接服务器端,指定:服务器端IP、端口号client_socket.connect(('127.0.0.1',8080))# 3.接收服务端的信息并打印data=client_socket.recv(1024).decode('utf-8')print(f"客户端收到数据:"+data)# 4.给服务器端发送消息client_socket.send("Socket很有趣,很喜欢!".encode('utf-8'))# 5.释放资源client_socket.close()

2.3 字符串 str 与二进制 bytes 类型转换:

在网络中,数据是以二进制数据类型bytes的形式进行传递的,所以在我们向网络传输数据的时候需要把数据转化成二进制,从网络中接受到的数据默认也是二进制类型的数据,想要正常使用这些数据也需要把这些数据从二进制类型数据转为字符串str型
①字符串str数据转换为二进制bytes类型时,可使用如下函数:

encode(encoding)用于把字符串编码转换为二进制数据,其中encoding表示编码格式,常设置为utf-8

②二进制bytes数据转换为字符串str类型时,可使用如下函数:

decode(encoding)用于把二进制数据解码转换为宇符串,其中encoding表示编码格式,常设置为utf-8

③说明:
1.编码(encode) 是把我们看懂的转成看不懂的:字符串.encode(码表);(不写默认utf-8编码)
2.解码(decode) 是把我们看不懂的转成看懂的:二进制.decode(码表);(不写默认utf-8编码)
3.只要是乱码了,原因一定是编解码不同;
4.数字、字母、特殊符号无论什么码表都只占一个字节,中文在gbk中占两个字节、utf-8中占三个字节;
5.二进制特殊写法:b'数字/ 字母/ 特殊符号',但该方式针对中文无效;

④代码示例:

# 1.编码s1="aB啦2@#"print(s1.encode())#运行结果:b'aB\xe5\x95\xa62@#'print(s1.encode('utf-8'))#运行结果:b'aB\xe5\x95\xa62@#'print(s1.encode('gbk'))#运行结果:b'aB\xc0\xb22@#'# 2.解码bys=b'aB\xe5\x95\xa62@#'print(type(bys))#运行结果:<class 'bytes'>print(bys.decode())#运行结果:aB啦2@#print(bys.decode('utf-8'))#运行结果:aB啦2@#print(bys.decode('gbk'))#运行结果:报错
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 0:09:23

从K210到舵机:一个电赛声源定位系统的实战开发笔记

1. 从零搭建声源定位系统的硬件选型 第一次接触电赛声源定位题目时&#xff0c;我和队友们花了整整三天时间在硬件方案论证上。市面上常见的方案主要有三种&#xff1a;STM32独立麦克风模块、K210官方圆形麦克风阵列、K210自制线性阵列。我们最终选择了第三种方案&#xff0c;这…

作者头像 李华
网站建设 2026/4/17 0:08:48

【JVM深度解析】第06篇:G1垃圾收集器深度解析

摘要 G1&#xff08;Garbage-First&#xff09;垃圾收集器是 JDK 9 的默认 GC&#xff0c;通过将堆划分为等大小的 Region 区域&#xff0c;彻底摒弃了传统的物理连续分代结构&#xff0c;实现了可预测的停顿时间模型。本文深入解析 G1 的核心设计&#xff1a;Region 分区机制…

作者头像 李华
网站建设 2026/4/17 0:06:53

大模型微调技术精要:小白程序员必备,助你秋招收藏必备!

本文从大模型微调技术概要出发&#xff0c;结合秋招面试高频问题&#xff0c;详细解析了LoRA微调原理、Prompt微调技术以及参数高效微调PEFT和指令微调SFT等核心知识点。文章还涵盖了微调技术选型、Loss计算、数据集收集、避免灾难性遗忘等实用技巧&#xff0c;并介绍了fp16和b…

作者头像 李华
网站建设 2026/4/17 0:06:03

java.lang.UnsupportedClassVersionError

引言:一个看似简单却暗藏玄机的错误 在 Java 开发与运维的日常中,开发者们常常会遇到形形色色的异常。有些异常如 NullPointerException 航行于代码逻辑的浅滩,容易定位;而另一些则如 java.lang.UnsupportedClassVersionError,它潜伏在编译与运行环境的交界处,像一道无形…

作者头像 李华
网站建设 2026/4/17 0:05:26

如何统一SQL视图报错信息_使用异常处理机制包装视图

SQL Server视图不支持TRY…CATCH&#xff0c;需用存储过程包装并加异常处理&#xff1b;PostgreSQL可用函数EXCEPTION块实现&#xff0c;返回TABLE或JSONB&#xff1b;应用层仍需统一捕获和分类错误。SQL Server 视图里没法直接写 TRY…CATCH&#xff1f;对&#xff0c;TRY...C…

作者头像 李华