主页 > 创业  > 

Python学习之网络编程

Python学习之网络编程
一,网络编程基本概念

网络编程是通过编写代码实现计算机之间的通信,它涵盖了许多重要的概念和技术,以下是一些关键概念的介绍:

1. Socket(套接字)

定义:Socket是计算机网络中用于进行通信的端点,它提供了一个应用层与传输层之间的接口。通过Socket,程序可以与其他计算机进行数据交换。

作用:通过Socket,程序能够进行以下操作:创建连接、发送和接收数据、关闭连接等。最常见的Socket编程模型是基于TCP/IP协议的。

类型:

TCP Socket:面向连接的,使用TCP协议进行通信,确保数据的可靠性。

UDP Socket:无连接的,使用UDP协议进行通信,适用于实时性要求较高的应用,但不能保证数据的可靠性。

2. IP地址与端口 IP地址:每台连接到网络的设备都会分配一个唯一的IP地址(互联网协议地址),用于标识设备的网络位置。IP地址可以是IPv4(32位)或IPv6(128位)。端口号:端口号是区分同一台设备上不同服务的标识符。在一个IP地址下,可以有多个端口,通常端口号范围是0到65535,其中0到1023是“知名端口”,如HTTP(80)、HTTPS(443)、FTP(21)等。 3. TCP/IP协议栈

TCP/IP协议栈是现代计算机网络的基础。它分为多个层级,常见的有四层:

应用层:处理具体的应用协议,如HTTP、FTP、SMTP等。传输层:提供端到端的通信功能,主要协议为TCP(传输控制协议)和UDP(用户数据报协议)。网络层:负责数据包的路由和传输,核心协议为IP(互联网协议)。数据链路层:在物理介质上传输数据包,确保数据的可靠传输。 4. TCP与UDP

TCP(传输控制协议):

面向连接:在发送数据前,必须建立连接(如通过三次握手过程)。可靠性:TCP保证数据的可靠性,通过确认(ACK)、重传机制、顺序控制等手段来确保数据按顺序且无误到达。应用:适用于需要高可靠性的应用,如网页浏览(HTTP)、文件传输(FTP)等。

UDP(用户数据报协议):

无连接:无需建立连接,直接发送数据。不保证可靠性:UDP不保证数据的可靠到达,也不保证数据的顺序,适用于对实时性要求高的应用(如视频会议、实时游戏等)。应用:常用于实时通信、流媒体传输等场景。 5. 三次握手与四次挥手

三次握手(TCP连接建立过程):

SYN:客户端向服务器发送连接请求(SYN标志位)。SYN-ACK:服务器响应客户端的请求,并确认收到连接请求。ACK:客户端向服务器确认连接建立完毕,连接正式建立。

四次挥手(TCP连接关闭过程):

客户端发起连接关闭请求(FIN标志位)。服务器响应并确认(ACK)。服务器关闭连接并发送FIN请求。客户端确认关闭连接。 6. DNS(域名系统) 定义:DNS是一种将域名(如 .example )转换为IP地址(如192.168.1.1)的系统。因为人类更容易记住域名而不是数字形式的IP地址,所以DNS提供了一个可读性更强的映射。工作原理:当用户访问一个网站时,计算机会查询DNS服务器,获取域名对应的IP地址,之后通过这个IP地址与服务器建立连接。 7. HTTP与HTTPS HTTP(超文本传输协议):HTTP是Web的基础协议,用于客户端与服务器之间的请求和响应。它是无状态的,每次请求都是独立的。HTTPS(安全超文本传输协议):HTTPS是在HTTP上加入了SSL/TLS协议,提供了加密和身份验证功能,确保数据传输的安全性,防止中间人攻击。 8. WebSocket 定义:WebSocket是一种基于TCP的协议,允许在客户端和服务器之间建立持久的双向通信。与传统的HTTP不同,WebSocket支持实时数据交换,适用于需要实时更新的应用场景,如在线聊天、实时股票交易等。 9. 代理服务器与负载均衡 代理服务器:代理服务器位于客户端和目标服务器之间,转发客户端的请求到目标服务器。它可以隐藏客户端的真实IP地址,增强安全性,或者缓存数据以提高访问速度。负载均衡:负载均衡是一种技术,通过将请求分配到多个服务器来分散负载,保证应用的高可用性和高性能。 10. 网络安全 加密与解密:在传输过程中,数据可能会被窃取。加密可以保证数据的保密性,常用的加密算法有对称加密(如AES)和非对称加密(如RSA)。身份验证与授权:确保通信双方身份的合法性,并根据授权控制对资源的访问,常见方法有使用证书、OAuth等。防火墙:防火墙可以监控和过滤网络流量,防止恶意访问或攻击。
二,网络协议概述 1. OSI模型与TCP/IP模型

网络协议通常是按照网络协议模型来设计的,最经典的模型是OSI七层模型和TCP/IP协议栈。两者在结构上有所不同,但目的都是为了标准化网络通信。

OSI七层模型: 物理层(Physical Layer):定义物理设备的传输媒介,如电缆、光纤等。数据链路层(Data Link Layer):提供节点到节点的通信,常用协议如Ethernet、PPP。网络层(Network Layer):负责数据包的路由与转发,核心协议是IP协议(Internet Protocol)。传输层(Transport Layer):提供端到端的数据传输,常见协议有TCP、UDP。会话层(Session Layer):管理应用间的会话和数据交换,典型协议有NetBIOS。表示层(Presentation Layer):数据格式的转换,如加密、解密等。应用层(Application Layer):实现具体的应用协议,如HTTP、FTP、SMTP等。 TCP/IP协议栈: 包括应用层、传输层、网络层和数据链路层,实际网络协议栈中的层次较为简化。 2. 常见的网络协议 1. IP协议(Internet Protocol) IP协议是网络层协议,负责在网络中传输数据包。它的主要作用是路由:根据目标IP地址,将数据从源计算机发送到目的计算机。IP协议有两个版本: IPv4(32位地址,表示范围为0.0.0.0到255.255.255.255);IPv6(128位地址,表示范围非常大,解决了IPv4地址耗尽的问题)。 2. TCP协议(Transmission Control Protocol) TCP协议是传输层的面向连接的协议。它提供可靠的、无差错的数据传输。TCP保证数据包按顺序到达,并支持错误检测、重传和流量控制。TCP广泛用于需要高可靠性的应用,如网页浏览(HTTP)、电子邮件(SMTP)等。三次握手:建立连接时,客户端和服务器通过三次握手过程确认通信准备就绪。四次挥手:断开连接时,客户端和服务器通过四次挥手关闭连接。 3. UDP协议(User Datagram Protocol) UDP协议是传输层的无连接协议。与TCP不同,UDP不保证数据的可靠到达和顺序,适用于实时应用,如视频流、语音通信等。UDP传输效率较高,但可能出现数据丢失和乱序的情况。TCP与UDP的对比 特性TCPUDP连接方式面向连接,需建立连接无连接,直接发送数据可靠性保证数据可靠传输不保证数据可靠性数据顺序保证数据顺序到达不保证数据顺序流量控制支持流量控制不支持流量控制拥塞控制支持拥塞控制不支持拥塞控制传输效率较低,因需要建立连接和进行错误处理较高,适合低延迟要求的应用数据重传自动重传丢失的数据包不进行重传头部大小20字节(不含数据)8字节适用场景文件传输、网页浏览、电子邮件等实时通信、视频会议、在线游戏等 4. HTTP协议(HyperText Transfer Protocol) HTTP协议是应用层的协议,用于客户端与Web服务器之间的请求和响应。它基于请求/响应模型,不保证数据传输的可靠性,因此常与TCP/IP一起使用。HTTPS是其安全版本,使用TLS/SSL协议加密传输数据,确保通信的安全。 5. DNS协议(Domain Name System) DNS协议是用于将域名(如 .example )解析为IP地址的协议。用户通过域名访问网站时,DNS会将域名转换为相应的IP地址,从而完成路由。 6. FTP协议(File Transfer Protocol) FTP协议是用于在计算机之间传输文件的协议。它工作在客户端和服务器之间,支持上传、下载文件。FTP支持两种模式:主动模式和被动模式。 7. SMTP协议(Simple Mail Transfer Protocol) SMTP协议是用于电子邮件传输的协议。它负责在邮件服务器之间传送邮件,通常与POP3或IMAP协议配合使用,POP3/IMAP用于邮件的接收和存储。 8. POP3/IMAP协议 POP3和IMAP都是用于电子邮件接收的协议: POP3:将邮件从邮件服务器下载到本地设备,下载后邮件通常从服务器删除。IMAP:将邮件存储在邮件服务器上,用户可以在不同设备上查看邮件,邮件在服务器上保持不变。 9. ARP协议(Address Resolution Protocol) ARP协议用于在局域网内解析IP地址与MAC地址的映射关系。当一个设备知道目标IP地址时,ARP协议帮助它找到目标设备的MAC地址,从而完成数据链路层的通信。 10. DHCP协议(Dynamic Host Configuration Protocol) DHCP协议用于动态分配IP地址给网络中的设备。设备在连接到网络时,DHCP服务器为其分配一个IP地址、子网掩码、网关等网络配置。 3. 网络协议的作用和特性 数据格式化:协议规定了数据的格式、结构以及传输顺序。错误检测和修正:大多数协议会包含机制来检测和修复传输中的错误,特别是像TCP这样的可靠协议。数据加密与安全性:协议可以通过加密机制来保证数据在传输过程中的安全性,如HTTPS协议。路由和流量控制:某些协议,如IP协议,负责在网络中转发数据包,确保数据包能够到达目的地。传输层协议如TCP还会进行流量控制和拥塞管理。 4. 协议的分类

根据协议的作用和层级,网络协议大致可以分为:

应用层协议:直接为应用程序提供服务,如HTTP、FTP、DNS、SMTP等。传输层协议:处理端到端的通信,确保数据的可靠传输,如TCP和UDP。网络层协议:负责数据包的路由和传输,如IP协议。数据链路层协议:确保在物理链路上正确传输数据,如Ethernet、PPP等。
三,Socket详解

Socket(套接字)是计算机网络中用于实现数据通信的基本组件,它为程序提供了一个接口,通过这个接口,应用程序可以向网络上的其他设备发送和接收数据。简而言之,Socket是通信的“端点”,它通过网络协议(如TCP或UDP)与其他计算机进行通信。

Socket编程通常是实现客户端与服务器之间通信的关键技术之一。以下是Socket的详细介绍,包括其基本概念、类型、工作原理以及如何在实际应用中使用。


1. Socket的基本概念 什么是Socket?

Socket是一个抽象的网络通信接口,通过它,应用程序可以通过操作系统提供的网络协议与其他主机进行通信。它是程序和协议之间的一个抽象层,提供了对网络通信的简单操作接口。通过Socket,程序可以完成:

打开网络连接向网络发送和接收数据关闭连接

每个Socket都需要指定通信的协议(如TCP或UDP)和相应的端口号,系统将根据这些信息来正确地路由数据。

Socket的组成

Socket通常由以下几部分组成:

IP地址:标识计算机在网络中的位置,通常是一个IPv4或IPv6地址。端口号:用于区分同一台机器上不同的服务或应用程序,端口号通常在0到65535之间,0到1023是“知名端口”。协议类型:TCP(面向连接,可靠)或UDP(无连接,不可靠)。
2. Socket的类型

根据协议的不同,Socket可以分为以下几种类型:

1. 流式Socket(Stream Socket) 协议:TCP特点:流式Socket是面向连接的,数据传输保证顺序、可靠性和完整性。通信前必须先建立连接,通信过程中保证数据无误。应用场景:适用于需要高可靠性、顺序保证的应用,如HTTP、FTP、SMTP等。 2. 数据报Socket(Datagram Socket) 协议:UDP特点:数据报Socket是无连接的,数据包可能丢失、乱序、重复,发送方不会等待接收方确认。其优势是传输速度快,但不可靠。应用场景:适用于实时性要求较高、容忍丢包的应用,如视频会议、在线游戏、DNS查询等。 3. 原始Socket(Raw Socket) 协议:ICMP、IP等特点:原始Socket允许应用程序直接访问底层网络协议,如IP协议。它通常用于需要构造和发送自定义网络数据包的应用。应用场景:网络安全(如防火墙、嗅探器)、网络测试工具等。
3. Socket的工作原理

Socket的工作过程通常分为两个部分:客户端和服务器。下面是Socket在客户端和服务器端的基本工作流程。

1. 服务器端Socket流程 创建Socket:服务器端创建一个Socket对象,指定协议(通常是TCP)。绑定端口:服务器通过bind()方法将Socket与指定的IP地址和端口号绑定。监听连接:服务器调用listen()方法,进入监听状态,等待客户端的连接请求。接受连接:当客户端请求连接时,服务器通过accept()方法接受连接,并创建一个新的Socket对象与客户端进行通信。接收和发送数据:服务器和客户端之间通过recv()和send()方法交换数据。关闭连接:通信结束后,服务器调用close()方法关闭Socket连接。 2. 客户端Socket流程 创建Socket:客户端首先创建一个Socket对象,指定协议(通常是TCP)。连接服务器:客户端通过connect()方法与服务器建立连接,指定目标IP地址和端口号。发送请求:客户端通过send()方法发送请求数据到服务器。接收响应:客户端通过recv()方法接收服务器的响应数据。关闭连接:通信完成后,客户端通过close()方法关闭Socket连接。
4. 常用Socket API

以下是常见的Socket操作及其使用方式。以Python为例,Java、C等语言也有类似的API:

1. Python中的Socket API

创建Socket:

import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET表示IPv4,SOCK_STREAM表示TCP

绑定IP和端口:

s.bind(('localhost', 12345)) # 绑定到本地IP和端口

监听连接:

s.listen(5) # 最多允许5个连接排队

接受连接:

client_socket, client_address = s.accept() # 等待客户端连接

连接到服务器(客户端):

s.connect(('localhost', 12345)) # 连接到指定的服务器和端口

发送数据:

s.send(b'Hello, World!') # 发送数据,数据必须是字节串

接收数据:

data = s.recv(1024) # 接收最多1024字节的数据

关闭连接:

s.close() # 关闭Socket连接 2. 主要的Socket方法 socket():创建一个新的Socket对象。bind(address):将Socket与指定的地址(IP地址和端口号)绑定。listen(backlog):开始监听连接。backlog指定最大排队连接数。accept():接受一个新的连接请求,返回一个新的Socket对象和客户端的地址。connect(address):客户端连接到指定的服务器地址。send(data):发送数据到远程计算机。recv(buffer_size):接收从远程计算机发送的数据。close():关闭Socket连接。
5. Socket的应用示例 1. 简单的TCP客户端和服务器 TCP服务器(Python示例) import socket # 创建Socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定地址和端口 server_socket.bind(('localhost', 12345)) # 开始监听连接 server_socket.listen(5) print('Server is listening...') while True: # 接受连接 client_socket, client_address = server_socket.accept() print(f'Connection from {client_address} has been established.') # 接收客户端数据 data = client_socket.recv(1024) print(f'Received from client: {data.decode()}') # 发送响应 client_socket.send(b'Hello, Client!') # 关闭连接 client_socket.close() TCP客户端(Python示例) import socket # 创建Socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接到服务器 client_socket.connect(('localhost', 12345)) # 发送数据 client_socket.send(b'Hello, Server!') # 接收响应 response = client_socket.recv(1024) print(f'Received from server: {response.decode()}') # 关闭连接 client_socket.close()
四,Socket模块 1. 基本概念

在socket模块中,最重要的概念是Socket对象。它代表了一个网络通信的端点,通过该对象可以与其他计算机上的应用程序进行通信。Socket对象通常由以下参数组成:

地址族(Address Family):表示Socket使用的地址类型。 socket.AF_INET:IPv4地址族。socket.AF_INET6:IPv6地址族。socket.AF_UNIX:Unix域套接字。 套接字类型(Socket Type):定义Socket使用的通信协议。 socket.SOCK_STREAM:TCP协议,面向连接的流式通信。socket.SOCK_DGRAM:UDP协议,无连接的报文传输。 协议:一般情况下由操作系统根据地址族和套接字类型自动选择协议。
2. 常用的socket方法 2.1 创建Socket import socket # 创建一个IPv4、TCP的Socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.AF_INET:表示使用IPv4地址。socket.SOCK_STREAM:表示使用TCP协议。 2.2 绑定地址和端口 (bind)

服务器需要通过bind()方法将Socket绑定到指定的IP地址和端口号上。

s.bind(('localhost', 12345)) # 绑定IP和端口 第一个参数是一个元组,包含了服务器的IP地址和端口号。localhost表示本地计算机,12345是监听的端口。 2.3 开始监听连接 (listen)

服务器端调用listen()方法来开启监听状态,等待客户端连接。

s.listen(5) # 允许最多5个客户端连接 5表示服务器可以同时处理的最大排队连接数。 2.4 接受客户端连接 (accept)

服务器端通过accept()方法接受客户端的连接请求。

client_socket, client_address = s.accept() # 接受连接 print(f"Connection from {client_address}") accept()方法会阻塞,直到客户端发起连接。它返回一个新的Socket对象和客户端的地址。 2.5 客户端连接 (connect)

客户端通过connect()方法与服务器建立连接,指定服务器的IP和端口。

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 12345)) # 连接服务器 2.6 发送数据 (send 和 sendall)

通过send()方法发送数据。数据必须是字节(bytes)格式。

client_socket.send(b'Hello, Server!') # 发送字节数据 send()发送的数据可能没有完全发送完,如果需要确保数据完整发送,建议使用sendall()。 client_socket.sendall(b'Hello, Server!') # 确保发送完数据 2.7 接收数据 (recv)

recv()方法用于接收数据。它返回的是字节数据。

data = client_socket.recv(1024) # 接收最多1024字节的数据 print(f"Received: {data.decode()}") # 解码为字符串并打印 recv()方法的参数是缓冲区的大小,表示每次最多接收多少字节的数据。 2.8 关闭Socket连接 (close)

通信完成后,调用close()方法关闭Socket连接。

client_socket.close()
3. 示例:TCP服务器与客户端 3.1 TCP服务器端(Python示例) import socket def start_server(): # 创建一个TCP Socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP和端口 server_socket.bind(('localhost', 12345)) # 开始监听客户端连接 server_socket.listen(5) print('Server is listening...') while True: # 接受客户端连接 client_socket, client_address = server_socket.accept() print(f'Connection from {client_address}') # 接收数据 data = client_socket.recv(1024) if data: print(f'Received: {data.decode()}') # 发送响应数据 client_socket.sendall(b'Hello, Client!') # 关闭客户端连接 client_socket.close() if __name__ == '__main__': start_server() 3.2 TCP客户端(Python示例) import socket def start_client(): # 创建一个TCP Socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接到服务器 client_socket.connect(('localhost', 12345)) # 发送数据 client_socket.sendall(b'Hello, Server!') # 接收服务器响应 response = client_socket.recv(1024) print(f'Received from server: {response.decode()}') # 关闭连接 client_socket.close() if __name__ == '__main__': start_client()
4. UDP通信

UDP通信不需要建立连接,发送数据和接收数据非常简单。下面是一个简单的UDP服务器和客户端示例。

4.1 UDP服务器端(Python示例) import socket def start_udp_server(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP Socket # 绑定IP和端口 server_socket.bind(('localhost', 12345)) print('Server is waiting for messages...') while True: # 接收数据 data, client_address = server_socket.recvfrom(1024) print(f'Received message: {data.decode()} from {client_address}') # 发送响应数据 server_socket.sendto(b'Hello, Client!', client_address) if __name__ == '__main__': start_udp_server() 4.2 UDP客户端(Python示例) import socket def start_udp_client(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP Socket # 发送数据 client_socket.sendto(b'Hello, Server!', ('localhost', 12345)) # 接收响应 data, server_address = client_socket.recvfrom(1024) print(f'Received from server: {data.decode()}') # 关闭连接 client_socket.close() if __name__ == '__main__': start_udp_client()
5. 其他常用功能 5.1 设置Socket超时 (settimeout)

settimeout()方法可以设置Socket的超时时间,单位为秒。超时后,recv()或accept()等方法将抛出socket.timeout异常。

s.settimeout(5) # 设置超时时间为5秒 5.2 获取本地地址 (getsockname)

getsockname()方法可以获取当前Socket的本地地址。

address = s.getsockname() print(f'Local address: {address}') 5.3 获取远程地址 (getpeername)

getpeername()方法可以获取当前Socket连接的远程地址。

address = s.getpeername() print(f'Remote address: {address}')
6. 总结 Python的socket模块提供了丰富的功能,能够实现基于TCP和UDP协议的网络通信。使用socket模块,你可以轻松创建客户端和服务器应用程序,进行数据发送和接收。常见的Socket方法包括bind()、listen()、accept()、connect()、send()、recv()等。对于UDP通信,sendto()和recvfrom()代替了send()和recv(),且不需要建立连接。
五,TCP编程 1. TCP服务器编程步骤 创建Socket对象:使用socket.socket()创建一个Socket对象,指定地址族为IPv4(AF_INET)和协议为TCP(SOCK_STREAM)。绑定端口:使用bind()方法将Socket绑定到一个IP地址和端口上。监听连接:使用listen()方法让服务器开始监听客户端的连接请求。接受连接:通过accept()方法接受客户端的连接请求。数据传输:通过recv()接收客户端数据,使用send()或sendall()发送数据到客户端。关闭连接:通信完成后,调用close()方法关闭Socket连接。 实例一,TCP服务端编程编写 from socket import socket,AF_INET,SOCK_STREAM #AF_INET 用于Internet之间的进程通信 #SOCK_STREAM 表示为TCP协议编程 #1,创建socket对象 server_socket=socket(AF_INET,SOCK_STREAM) #2,绑定IPA地址和端口 ip='127.0.0.1' port=8888 server_socket.bind((ip,port)) #3,使用listen()开始监听 server_socket.listen(5) print('服务器已经启动') #4,等待客户端的连接 client_socket,client_addr=server_socket.accept() #系列解包赋值 #5,接受来自客户端的数据 date=client_socket.recv(1024) print('客户端发送过来的数据为date',date.decode('utf-8')) #要求客户端发送过来的数据使用utf-8编码 #6,关闭socket server_socket.close() 2.TCP客户端编程基本流程 创建Socket对象:客户端通过socket.socket()创建一个Socket对象,并指定使用的地址族(通常是IPv4)和协议(通常是TCP)。连接服务器:客户端通过connect()方法与服务器建立连接,指定服务器的IP地址和端口号。发送数据:客户端使用send()或sendall()方法将数据发送到服务器。接收数据:客户端通过recv()方法接收服务器返回的响应数据。关闭连接:通信结束后,客户端使用close()方法关闭Socket连接。 实例二,TCP客户端编程编写

要求新创建一个项目编写python代码,以便作为区分。并且新开启一个窗口以打开这个新python文件

import socket #1,创建socket对象 client_socket=socket.socket() #2,写入服务端IP地址与主机端口 ip='127.0.0.1' port=8888 client_socket.connect((ip,port)) print('与服务器连接建立成功') #3,发送数据 client_socket.send('hello python'.encode('utf-8')) #4,关闭 client_socket.close() print('发送完毕')

TCP编程客户端启动运行有先后,先启动运行服务端再启动运行客户端,连接建立之后双方谁先发送数据均可

实例三,TCP多次通信服务器端代码编写 import socket #1,创建socket对象 socket_obj=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2,绑定主机IP端口 socket_obj.bind(('127.0.0.1',8888)) #3,设置最大的连接数量 socket_obj.listen(5) #4,等待客户端的TCP连接 client_socket,client_addr=socket_obj.accept() #5,接受数据 info=socket_obj.recv(1024).decode('utf-8') while info != 'bye': if info != '': print('接受到的数据是:',info) #准备发送数据 date=input('请输入要发送的数据:') #服务器端回复客户端 socket_obj.send(date.encode('utf-8')) if date == 'bye': break info=socket_obj.recv(1024).decode('utf-8') #关闭socket对象 client_socket.close() socket_obj.close() 实例四,TCP多次通信客户器端代码编写 import socket #1,创建socket对象 client_socket=socket.socket() #2,主机的IP与端口 client_socket.connect(('127.0.0.1',8888)) print('已经建立服务器连接') #3,客户端先发送数据 info='' while info !='bye': #准备发送的数据 send_data=input('请输入要发送的数据:') client_socket.send(send_data.encode('utf-8')) #判断 if send_data=='bye': break #接收一条数据 info=client_socket.recv(1024).decode('utf-8') print('接受到服务器的响应数据:',info) #关闭socket对象 client_socket.close() 常见TCP客户端的改进和扩展 1. 设置Socket超时(settimeout)

客户端可以通过settimeout()方法设置Socket的超时时间。如果在指定时间内没有收到响应,recv()方法会抛出socket.timeout异常。

client_socket.settimeout(5) # 设置5秒超时 超过5秒没有数据接收,recv()方法会抛出timeout异常。 2. 发送和接收更大的数据

如果需要发送或接收比1024字节更大的数据,可以调整缓冲区大小,或者分多次发送和接收。

client_socket.sendall(b"Large Data" * 1000) # 发送更大的数据 3. 异常处理

在实际应用中,TCP客户端应处理可能的异常,如连接失败、发送失败等。

try: client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 12345)) except socket.error as e: print(f"Error occurred: {e}") finally: client_socket.close() 通过try-except-finally语句捕获并处理Socket异常。 3 TCP服务端(线程池方式)

为了更有效地管理多个客户端连接,可以使用线程池来代替创建一个新的线程。

import socket import threading from concurrent.futures import ThreadPoolExecutor # 处理客户端连接的函数 def handle_client(client_socket, client_address): print(f"New connection from {client_address}") # 接收客户端数据 data = client_socket.recv(1024) # 接收最多1024字节的数据 print(f"Received from {client_address}: {data.decode()}") # 发送响应 client_socket.sendall(b"Hello, Client!") # 关闭连接 client_socket.close() print(f"Connection with {client_address} closed.") def start_tcp_server(): # 1. 创建Socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 绑定IP和端口 server_socket.bind(('localhost', 12345)) # 3. 开始监听连接,最多允许5个客户端排队 server_socket.listen(5) print("Server is listening on port 12345...") # 4. 创建线程池来管理客户端连接 with ThreadPoolExecutor(max_workers=5) as executor: # 5. 处理多个客户端连接 while True: # 接受客户端连接 client_socket, client_address = server_socket.accept() # 将每个连接任务提交给线程池 executor.submit(handle_client, client_socket, client_address) if __name__ == "__main__": start_tcp_server()

解释:

ThreadPoolExecutor:通过线程池来管理线程,避免每次都创建新的线程。executor.submit():将处理客户端连接的任务提交给线程池中的空闲线程执行。
4. TCP服务端异常处理

在实际编程中,TCP服务端程序需要处理一些可能出现的异常,例如:

客户端断开连接网络异常连接超时

可以通过try/except语句来捕获异常并进行处理。例如:

try: client_socket, client_address = server_socket.accept() except socket.timeout: print("Connection timeout!") except Exception as e: print(f"Error: {e}")
六,UDP编程

UDP(用户数据报协议)是一个无连接的协议,与TCP不同,UDP不需要建立连接和确认数据是否成功到达,因此它的传输效率更高,但也不保证数据的可靠性和顺序性。在UDP中,数据被以“数据报”的形式发送,每个数据报都包含了目的地址和端口信息。

UDP编程相较于TCP编程简单,因为它不需要进行连接的建立与关闭。下面我们将介绍如何使用Python的socket模块进行UDP编程。

UDP客户端与服务器编程流程

创建UDP Socket对象:使用socket.socket()方法创建一个UDP的Socket对象。绑定端口(仅服务器端需要):服务器端需要通过bind()方法将Socket与IP地址和端口绑定。发送数据:客户端通过sendto()方法发送数据,数据将发送到目标IP地址和端口。接收数据:使用recvfrom()方法接收来自远程主机的数据。关闭连接:UDP没有连接的概念,但客户端和服务器使用close()来关闭Socket。
1. UDP服务器端编程 1.1 UDP服务器端代码

服务器端代码将创建一个UDP套接字,绑定本地IP和端口,接收客户端数据,并发送响应。

import socket def start_udp_server(): # 1. 创建UDP套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 绑定IP和端口 server_socket.bind(('localhost', 12345)) print("UDP server is waiting for messages...") while True: # 3. 接收客户端数据 data, client_address = server_socket.recvfrom(1024) # 最大接收1024字节 print(f"Received message from {client_address}: {data.decode()}") # 4. 发送响应数据 server_socket.sendto(b"Hello, Client!", client_address) if __name__ == "__main__": start_udp_server() 代码解析: socket.AF_INET:使用IPv4地址族。socket.SOCK_DGRAM:使用UDP协议。bind(('localhost', 12345)):将Socket绑定到localhost的12345端口。recvfrom(1024):接收客户端发送的数据,最多1024字节,返回的是数据和客户端的地址(client_address)。sendto(b"Hello, Client!", client_address):向客户端发送数据,client_address指定了客户端的地址和端口。
2. UDP客户端编程 2.1 UDP客户端代码

客户端创建一个UDP套接字,发送数据到服务器,并接收来自服务器的响应。

import socket def start_udp_client(): # 1. 创建UDP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 发送数据到服务器 message = "Hello, Server!" client_socket.sendto(message.encode(), ('localhost', 12345)) # 发送数据到服务器 # 3. 接收服务器的响应 response, server_address = client_socket.recvfrom(1024) # 接收来自服务器的响应 print(f"Received from server: {response.decode()}") # 4. 关闭连接 client_socket.close() if __name__ == "__main__": start_udp_client() 代码解析: socket.AF_INET:使用IPv4地址族。socket.SOCK_DGRAM:使用UDP协议。sendto(message.encode(), ('localhost', 12345)):通过sendto()方法将数据发送到指定的服务器IP和端口。发送的数据必须是字节类型,因此需要调用encode()。recvfrom(1024):接收来自服务器的数据,最多接收1024字节,并返回数据和服务器的地址。close():关闭Socket连接。
3. UDP编程的特点与优势 无连接性:UDP是无连接的协议,客户端和服务器不需要进行连接的建立和拆除。发送数据时无需确认接收方是否准备好接收。简单快速:由于没有连接的开销,UDP适合实时性要求高、数据量较小、丢包可以容忍的场景,例如视频流、语音通信、在线游戏等。不保证可靠性:UDP不会确保数据包的到达、顺序或完整性,数据包可能会丢失、重复或者顺序错乱。适用于广播和多播:UDP支持广播(将数据发送到网络中的所有主机)和多播(将数据发送到特定的一组主机)。
4. 异常处理

UDP虽然不需要建立连接,但客户端和服务器仍然可能遇到一些网络错误。可以使用try/except来捕获和处理异常。

import socket def start_udp_server(): try: server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind(('localhost', 12345)) print("UDP server is waiting for messages...") while True: data, client_address = server_socket.recvfrom(1024) print(f"Received message from {client_address}: {data.decode()}") server_socket.sendto(b"Hello, Client!", client_address) except socket.error as e: print(f"Socket error: {e}") finally: server_socket.close() print("Server socket closed.") if __name__ == "__main__": start_udp_server()

在此代码中,try-except用于捕获任何Socket错误,例如绑定失败或网络不可用等。


5. UDP与TCP的比较 特性UDPTCP连接类型无连接面向连接可靠性不可靠(可能丢包、重复、乱序)可靠(保证数据顺序和完整性)速度快速较慢(因有连接建立和确认机制)数据完整性需要应用层保证自动保证数据完整性和顺序适用场景实时通信(视频、音频、游戏等)文件传输、Web、电子邮件等应用
6. 总结 UDP编程通过Python的socket模块实现相对简单,适用于不需要高可靠性的场景。UDP的优势在于快速传输,不需要建立连接,因此适合实时性要求高的应用场景,但其不保证数据传输的可靠性和顺序性。UDP的缺点是它不提供数据包的完整性、顺序保证以及错误检测,所以开发者需要自己处理丢包、数据重发等问题。 实例一,UDP的发送方 from socket import socket,AF_INET, SOCK_DGRAM #1,创建socket对象 send_socket=socket(AF_INET,SOCK_DGRAM) #2,准备发送数据 date=input('输入需要发送的数据') #3,指定接收的IP和端口 ip_port=('127.0.0.1',8888) #4,发送数据 send_socket.sendto(date.encode('utf-8'),ip_port) #接收来自接收方的回复数据 recv_data,addr=send_socket.recvfrom(1024) print('接收到的数据为:',recv_data.decode('utf-8')) #5,关闭socketd对象 send_socket.close() 实例二,UDP的接收方 from socket import socket,AF_INET,SOCK_DGRAM #1,创建socket对象 recv_socket=socket(AF_INET,SOCK_DGRAM) #2,绑定IP地址和端口 recv_socket.bind(('127.0.0.1',8888)) #3,接收来自发送方的数据 recv_date,addr=recv_socket.recvfrom(1024) print('接收到的数据:',recv_date.decode('utf-8')) #4,准备回复对方的数据 date=input('请输入需要回复的数据') #5,回复 recv_socket.sendto(date.encode('utf-8'),addr) #6,关闭 recv_socket.close()

UDP编程接收方与发送方启动运行无先后,但先启动运行发送方,数据会丢包

实例三,模拟客服咨询小程序

客服端代码

from socket import socket,AF_INET,SOCK_DGRAM #1,创建socket对象 recv_socket=socket(AF_INET,SOCK_DGRAM) #2,绑定IP地址和端口 recv_socket.bind(('127.0.0.1',8888)) while True: #3,接收发送过来的数据 recv_data,addr=recv_socket.recvfrom(1024) print('客户说:',recv_data.decode('utf-8')) if recv_data.decode('utf-8') =='bye': break #4,准备回复对方的数据 date=input('客服回:') #5,发送 recv_socket.sendto(date.encode('utf-8'),addr) #6,关闭socket对象 recv_socket.close()

咨询端代码

from socket import socket,AF_INET,SOCK_DGRAM #1,创建socket对象 send_socket=socket(AF_INET,SOCK_DGRAM) while True: #2,准备发送的数据 date=input('客户说:') #3,发送 send_socket.sendto(date.encode('utf-8'),('127.0.0.1',8888)) if date == 'bye': break #4,接收来自客服端的回复 recv_data,addr=send_socket.recvfrom(1024) print('客服回:',recv_data.decode('utf-8')) #5,关闭socket对象 send_socket.close()
标签:

Python学习之网络编程由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Python学习之网络编程