4. 网络编程

张开发
2026/4/17 0:12:11 15 分钟阅读

分享文章

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包synj到服务器并进入 SYNSENT状态等待服务器确认SYN同步序列编号 Synchronize Sequence Numbers第二次握手 服务器收到 syn包必须确认客户的 SYNackj1同时自己也发送一个 SYN包SYNk即 SYNACK 包此时服务器进入 SYN_RECV状态第三次握手 客户端收到服务器的 SYNACK 包向服务器发送确认包 ACKackk1此时包发送完毕客户端和服务器进入 ESTABLISHEDTCP连接成功状态完成第三次握手完成三次握手客户端与服务器开始传送数据。)下图红线指的是三次握手建立连接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协议。参数1AddressFamily地址族。即Ipv4 还是 Ipv6默认值AF_INET(Ipv4)AF_INET6(Ipv6)参数2Type通信方式。socket类型即TCP 还是 UDP默认值SOCK_STREAM(TCP)SOCK_DGRAM(UDP)③示例#演示socket对象的创建importsocket#导入模块#创建socket对象tcp_socketsocket.socket(socket.AF_INET,socket.SOCK_STREAM)#输出内容print(tcp_socket)#运行结果# socket.socket fd3, familyAddressFamily.AF_INET, typeSocketKind.SOCK_STREAM, proto0, 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_socketsocket.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_infoserver_socket.accept()# 5.给客户端发送消息accept_socket.send(bWelcome to Python)# 6.接收客户端的信息并打印dataaccept_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_socketsocket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2.连接服务器端指定服务器端IP、端口号client_socket.connect((127.0.0.1,8080))# 3.接收服务端的信息并打印dataclient_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.编码s1aB啦2#print(s1.encode())#运行结果baB\xe5\x95\xa62#print(s1.encode(utf-8))#运行结果baB\xe5\x95\xa62#print(s1.encode(gbk))#运行结果baB\xc0\xb22## 2.解码bysbaB\xe5\x95\xa62#print(type(bys))#运行结果class bytesprint(bys.decode())#运行结果aB啦2#print(bys.decode(utf-8))#运行结果aB啦2#print(bys.decode(gbk))#运行结果报错

更多文章