Python Socket编程详解及实践指南
在如今的互联网当中,Socket 协议是最重要的基础之一。本文涵盖了在 Python 中处理 Socket 编程的所有领域。
为什么使用 Sockets
Sockets 是组成当今网络的各种通信协议,这些协议使得在两个不同的程序或设备之间传输信息成为可能。例如,当我们打开浏览器时,我们作为客户机就会创建与服务器的连接以传输信息。
在深入研究这个通信原理之前,让我们先弄清楚 Sockets 到底是什么。
什么是 Sockets
一般来说,Socket 是为发送和接收数据而构建的内部应用协议。单个网络将有两个 Sockets,每个 Sockets 用于通信设备或程序,这些 Sockets 是IP地址和端口的组合。根据使用的端口号,单个设备可以有“n”个 Sockets,不同的端口可用于不同类型的协议。
下图展示了一些常见端口号和相关协议的信息:
协议 |
端口号 |
Python 库 |
应用 |
HTTP |
80 |
httplib,urllib,requests |
网页,网站 |
FTP |
20 |
ftplib |
文件传输 |
NNTP |
119 |
nttplib |
新闻传输 |
SMTP |
25 |
smtplib |
发送邮件 |
Telnet |
23 |
telnetlib |
命令行 |
POP3 |
110 |
poplib |
接收邮件 |
Gopher |
70 |
gopherlib |
文档传输 |
现在我们已经了解了 Sockets 的概念,现在让我们来看看 Python 的 Socket 模块
如何在 Python 中实现 Socket 编程
要在 Python 中实现 Socket 编程,需要导入 socket 模块。
该模块的一些重要方法如下:
方法 |
描述 |
socket.socket() |
用于创建 socket(服务器端和客户端都需要创建) |
socket.accept() |
用于接受连接。它返回一对值(conn,address),其中conn是用于发送或接收数据的新 socket 对象,address是连接另一端的 socket 地址 |
socket.bind() |
用于绑定到指定为参数的地址 |
socket.close() |
用于关闭 socket |
socket.connect() |
用于连接到指定为参数的远程地址 |
socket.listen() |
使服务器能够接受连接 |
现在我们已经了解了 socket 模块的重要性,接下来让我们看看如何在 Python 中建服务器和客户机。
什么是服务器
服务器或者是一个程序、一台计算机,或者是一台专门用于管理网络资源的设备。服务器可以位于同一设备或计算机上,也可以本地连接到其他设备和计算机,甚至可以远程连接。有各种类型的服务器,如数据库服务器、网络服务器、打印服务器等。
服务器通常使用socket.socket(),socket.bind(),socket.listen()等来建立连接并绑定到客户端,现在让我们编写一个程序来创建服务器。
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((socket.gethostname(),1234)) #port number can be anything between 0-65535(we usually specify non-previleged ports which are > 1023) s.listen(5) while True: clt,adr=s.accept() print(f"Connection to {adr}established") #f string is literal string prefixed with f which #contains python expressions inside braces clt.send(bytes("Socket Programming in Python","utf-8 ")) #to send info to clientsocket
创建 socket 的第一个必要条件是导入相关模块。之后是使用socket.socket()方法创建服务器端 socket。
AF_INET 是指来自 Internet 的地址,它需要一对(主机、端口),其中主机可以是某个特定网站的 URL 或其地址,端口号为整数。SOCK_STREAM 用于创建 TCP 协议。
bind()方法接受两个参数作为元组(主机、端口)。这里需要注意的是最好使用4位的端口号,因为较低的端口号通常被占用或者是系统预留的。listen()方法允许服务器接受连接,5是同时接受的多个连接的队列。此处可以指定的最小值为0,如果未指定参数,则采用默认的合适参数。
while循环允许永远接受连接,clt和adr是客户端对象和地址,print语句只是打印出客户端 socket 的地址和端口号,最后,clt.send用于以字节为单位发送数据。
现在我们的服务器已经设置好了,让我们继续向客户机前进。
什么是客户端
客户端是从服务器接收信息或服务的计算机或软件。在客户端-服务器模型中,客户端从服务器请求服务。最好的例子是 Google Chrome、Firefox 等 Web 浏览器,这些 Web 浏览器根据用户的指示请求 Web 服务器提供所需的网页和服务。其他示例包括在线游戏、在线聊天等。
现在,让我们看看如何用 Python 编程语言编写客户端程序:
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2346)) msg=s.recv(1024) print(msg.decode("utf-8"))
首先依然是导入 socket 模块,然后像创建服务器时那样创建套接字。接着要在客户端服务器之间创建连接,需要通过指定(host,port)使用 connect()方法。
注意:当客户端和服务器位于同一台计算机上时,需要使用gethostname。(LAN–localip/WAN–publicip)
在这里,客户端希望从服务器接收一些信息,为此,我们需要使用recv()方法,信息存储在另一个变量msg中。需要注意的是正在传递的信息将以字节为单位,在上述程序的客户端中,一次传输最多可以接收1024字节(缓冲区大小)。根据传输的信息量,可以将其指定为任意数量。
最后,再解码并打印正在传输的消息。
现在我们已经了解了如何创建客户端-服务器程序,接下来让我们看看它们需要如何执行。
客户端服务器交互
要执行这些程序,需要打开命令程序,进入创建客户端和服务器程序的文件夹,然后键入:
py server.py #这里,server.py 是服务器的文件名
不出意外服务器开始运行
要执行客户端,需要打开另一个cmd窗口,然后键入:
pyclient.py
下面让我们将缓冲区大小减少到7,来看看相同的程序会怎么样
如图所示,传输7个字节后,连接终止。
其实这是一个问题,因为我们尚未收到完整的信息,但是连接却提前关闭了,下面让我们来解决这个问题。
多重通信
为了在客户端收到完整信息之前继续连接,我们可以使用while循环
import socket s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2346)) while True: msg=s.recv(7) print(msg.decode("utf-8"))
如此修改之后,每次传输将以7个字节接收完整消息。
但这又引来了另一个问题,连接永远不会终止,你永远不知道什么时候会终止。此外,如果我们实际上不知道客户端将从服务器接收到的消息或信息有多大,该怎么办。在这种情况下,我们需要继续完善代码
complete_info='' while True: msg = s.recv(7) if len(msg)<=0: break complete_info += msg.decode("utf-8") print(complete_info)
在服务器端,使用close()方法,如下所示:
clt.close()
输出如下:
程序会检查信息的大小,并将其打印到一次两个字节的缓冲区中,然后在完成连接后关闭连接。
传输 Python 对象
目前为止我们仅仅掌握了传递字符串的方法,但是,Python 中的 Socket 编程也允许我们传输 Python 对象。这些对象可以是集合、元组、字典等。要实现这一点,需要用到 Python 的 pickle 模块。
Python pickle模块
当我们实际序列化或反序列化 Python 中的对象时,就会使用到 Python pickle 模块。让我们看一个小例子
import pickle mylist=[1,2,'abc'] mymsg = pickle.dumps(mylist) print(mymsg)
Output:
b’x80x03]qx00(Kx01Kx02Xx03x00x00x00abcqx01e.’
在上面的程序中,mylist是使用pickle模块的dumps()函数序列化的。还要注意,输出以b开头,表示它已转换为字节。在 socket 编程中,可以实现此模块以在客户端和服务器之间传输 python 对象。
如何使用 pickle 模块传输 Python 对象
当我们将 pickle 与 socket 一起使用时,完全可以通过网络传输任何内容。
先来看看服务端代码
Server-Side:
import socket import pickle a=10 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((socket.gethostname(), 2133))#binding tuple s.listen(5) while True: clt , adr = s.accept() print(f"Connection to {adr}established") m={1:"Client", 2:"Server"} mymsg = pickle.dumps(m)#the msg we want to print later mymsg = {len(mymsg):{a}}"utf-8") + mymsg clt.send(mymsg)
这里,m是一个字典,它基本上是一个需要从服务器发送到客户端的 Python 对象。这是通过首先使用dumps()序列化对象,然后将其转换为字节来完成的。
现在,让我们记下客户端:
Client-Side:
import socket import pickle a=10 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 2133)) while True: complete_info = b'' rec_msg = True while True: mymsg = s.recv(10) if rec_msg: print(f"The length of message = {mymsg[:a]}") x = int (mymsg[:a ] ) rec_msg = False complete_info += mymsg if len(complete_info)-a == x: print("Recieved the complete info") print(complete_info[a:]) m = pickle.loads(complete_info[a:]) print(m) rec_msg = True complete_info = b'' print(complete_info)
第一个while循环将帮助我们跟踪完整的消息(complete_info)以及正在使用缓冲区接收的消息(rec_msg)。
然后,在接收消息时,我们所做的就是打印每一位消息,并将其放在大小为10的缓冲区中接收。此大小可以是任何大小,具体取决于个人选择。
然后如果收到的消息等于完整消息,我们只会将消息打印为收到的完整信息,然后使用loads()反序列化消息。
输出如下:
以上是Python Socket编程详解及实践指南的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

如果您在Windows11上突然出现缓慢的互联网连接,并且您已经尝试了书中的所有技巧,那么它可能与您的网络无关,而是与您的最大传输单元(MTU)无关。如果您的系统发送或接收具有错误MTU大小的数据,则可能会出现问题。在这篇文章中,我们将了解如何在Windows11上更改MTU大小以实现流畅和不间断的互联网连接。Windows11中的默认MTU大小是多少?Windows11中的默认MTU大小为1500,这是允许的最大值。MTU代表最大传输单位。这是可以在网络上发送或接收的最大数据包大小。每个支持网
![WLAN扩展模块已停止[修复]](https://img.php.cn/upload/article/000/465/014/170832352052603.gif?x-oss-process=image/resize,m_fill,h_207,w_330)
如果您的Windows计算机上的WLAN扩展模块出现问题,可能会导致您与互联网断开连接。这种情况常常让人感到困扰,但幸运的是,本文提供了一些简单的建议,可以帮助您解决这个问题,让您的无线连接重新正常运行。修复WLAN扩展模块已停止如果您的Windows计算机上的WLAN可扩展性模块已停止工作,请按照以下建议进行修复:运行网络和Internet故障排除程序禁用并重新启用无线网络连接重新启动WLAN自动配置服务修改电源选项修改高级电源设置重新安装网络适配器驱动程序运行一些网络命令现在,让我们来详细看

我们在连接网络时需要使用正确的dns才可以上网。同理,如果我们使用了错误的dns设置就会提示dns服务器错误了,这时候我们可以尝试在网络设置中选择自动获取dns来解决,下面就一起来看下具体解决方法吧。win11网络dns服务器错误怎么办方法一:重新设置DNS1、首先,点击任务栏中的开始进入,在其中找到并点开“设置”图标按钮。2、然后点击左侧栏中的“网络&Internet”选项命令。3、然后在右侧找到“以太网”选项,点击进入。4、之后,点击DNS服务器分配中的“编辑”,最后将DNS设置为“自动(D

什么是“网络错误下载失败”问题?在我们深入研究解决方案之前,让我们首先了解“网络错误下载失败”问题的含义。当下载过程中网络连接中断时,通常会发生此错误。它可能由于各种原因而发生,例如互联网连接薄弱、网络拥塞或服务器问题。发生此错误时,下载将停止,并显示错误消息。如何修复失败的网络错误下载?在访问或下载必要的文件时,遇到“网络错误下载失败”可能会成为障碍。无论您是使用Chrome等浏览器还是Google云端硬盘和Google相册等平台,都会弹出此错误,从而造成不便。下面是帮助您导航和解决此问题的分

如果WDMyCloud未在Windows11的网络上显示,这可能是一个大问题,尤其是当您将备份或其他重要文件存储在其中时。对于经常需要访问网络存储的用户来说,这可能是一个大问题,因此在今天的指南中,我们将向您展示如何永久解决此问题。为什么WDMyCloud未显示在Windows11网络上?您的MyCloud设备、网络适配器或互联网连接未正确配置。电脑上未安装SMB功能。Winsock的临时故障有时会导致此问题。如果我的云未显示在网络上,我该怎么办?在我们开始修复问题之前,您可以执行一些初步检查:

这篇文章将介绍Win10系统网络显示地球标志但无法上网的解决方法。文章将提供详细的操作步骤,帮助读者解决Win10网络显示地球无法上网的问题。方法一:直接重启先检查一下网线是否没插好,宽带是否欠费,路由器或光猫可能会卡死,这时需重启路由器或光猫。假如当前电脑没有重要的事宜在操作,能直接重启电脑,大部分的小问题能通过重启电脑来快速解决。假如确定宽带没有欠费,网络正常,那便是另一回事。方法二:1、按【Win】键,或点击左下角的【开始菜单】,在打开的菜单项中,点击电源按钮上方的齿轮状图标,这个就是【设

LAN唤醒是Windows11上的一项网络功能,有了它,您可以远程将电脑从休眠或睡眠模式唤醒。虽然临时用户不经常使用它,但此功能对于使用有线网络的网络管理员和高级用户非常有用,今天我们将向您展示如何设置它。如何知道我的计算机是否支持LAN唤醒?要使用此功能,您的计算机需要以下各项:PC需要连接到ATX电源,以便您可以远程将其从睡眠模式唤醒。需要创建访问控制列表并将其添加到网络中的所有路由器。网卡需要支持唤醒局域网功能。要使此功能正常工作,两台计算机需要位于同一网络上。虽然大多数以太网适配器通过以

为了确保您的网络连接正常工作或解决问题,有时您需要检查Windows11上的网络连接详细信息。通过这样做,您可以查看各种信息,包括您的IP地址、MAC地址、链接速度、驱动程序版本等,在本指南中,我们将向您展示如何做到这一点。如何在Windows11上查找网络连接详细信息?1.使用“设置”应用按+键打开Windows设置。WindowsI接下来,导航到左窗格中的网络和互联网,然后选择您的网络类型。在我们的例子中,这就是以太网。如果您使用的是无线网络,请改为选择Wi-Fi网络。在屏幕底部,您应该会看
