当前位置: 首页 > 后端技术 > Python

什么是Python中的套接字编程?

时间:2023-03-26 14:09:23 Python

总结:本文涵盖了有关使用Python进行套接字编程的所有领域。套接字可以帮助您建立这些连接,而Python无疑会简化它们。本文分享自华为云社区《从零开始学python | 什么是Python中的套接字编程以及如何掌握它?》,原作者:雨川。不可否认,互联网已经成为以“连接”或“网络”为特征的“存在之魂”。使用套接字最关键的基础之一是使这些网络成为可能的原因。本文涵盖了有关使用Python进行套接字编程的所有领域。套接字可以帮助您建立这些连接,而Python无疑会简化它们。让我们快速浏览一下本文涵盖的所有主题:为什么使用套接字?什么是Python中的套接字?Python如何实现Socket编程什么是服务器?什么是客户端?Echo客户端-服务器多方通信传输Python对象Pythonpickle模块如何使用pickle模块传输python对象为什么要使用Sockets?套接字是网络的基础。它们可以在两个不同的程序或设备之间传输信息。例如,当您打开浏览器时,您作为客户端正在与服务器建立连接以进行信息传输。在深入探讨此通信之前,让我们首先弄清楚这些套接字到底是什么。什么是套接字?一般来说,套接字是为发送和接收数据而构建的内部端点。单个网络将有两个套接字,一个用于每个通信设备或程序。这些套接字是IP地址和端口的组合。根据使用的端口号,单个设备可以有n个插槽。不同的端口可用于不同类型的协议。看下图,了解一些常见的端口号和相关协议:了解了sockets的概念,我们再来看看Python的Socket模块:如何在Python中实现Socket编程:ToToimplementSocketprogramming在Python中,您需要导入套接字模块或框架。该模块包含创建套接字并帮助它们相互关联所需的内置方法。一些重要的方法如下:了解了socket模块的重要性之后,让我们继续看看它是如何为Python中的socket编程创建服务器和客户端的。什么是服务器?服务器可以是专用于管理网络资源的程序、计算机或设备。服务器可以在同一设备或计算机上,本地连接到其他设备和计算机,甚至可以远程连接。服务器有多种类型,如数据库服务器、Web服务器、打印服务器等,服务器通常使用socket.socket()、socket.bind()、socket.listen()等方法建立连接和绑定到客户端。现在,让我们编写一个程序来创建一个服务器。考虑以下示例:示例:importsockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.bind((socket.gethostname(),1234))#portnumber可以是0-65535之间的任何值(我们通常指定非特权端口>1023)s.listen(5)whileTrue:clt,adr=s.accept()print(f"Connectionto{adr}established")#fstring是以f为前缀的文字串#在大括号内包含python表达式clt.send(bytes("SocketProgramminginPython","utf-8"))#tosendinfotoclientsocket如您所见,创建套接字的第一个必要条件是导入套接字模块。之后,使用socket.socket()方法创建服务器端套接字。注意:AF_INET是指互联网上的一个地址,它需要一对(主机,端口),其中主机可以是特定网站的URL或其地址,端口号是一个整数。SOCK_STREAM用于创建TCP协议。bind()方法接受两个参数作为元组(主机、端口)。但是,最好使用4位端口号,因为通常使用较小的端口号。listen()方法允许服务器接受连接。这里,5是同时发生的多个连接的队列。可在此处指定的最小值为0(如果您提供较小的值,请将其更改为0)。如果未指定参数,则假定默认合适的参数。while循环允许永远接受连接。“clt”和“adr”是客户端对象和地址。打印语句只是打印出客户端套接字的地址和端口号。最后,clt.send用于发送字节数据。现在我们的服务器已准备就绪,让我们转到客户端。什么是客户?客户端是从服务器接收信息或服务的计算机或软件。在客户端-服务器模块中,客户端向服务器请求服务。最好的例子是Web浏览器,例如GoogleChrome、Firefox等。这些Web浏览器向Web服务器请求用户指示的所需网页和服务。其他的例子还有在线游戏,在线聊天等。下面我们看看如何用Python编程语言编写一个客户端程序:例子:importsockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((socket.gethostname(),2346))信息=s。recv(1024)print(msg.decode("utf-8"))第一步导入socket模块,然后创建socket,就像创建server一样。然后,要在客户端-服务器之间创建连接,您需要通过指定(host,port)使用connect()方法。注意:当客户端和服务器在同一台机器上时使用gethostname。(LAN–本地IP/WAN–公共IP)这里客户端想要从服务器接收一些信息,为此您需要使用recv()方法,并且此信息存储在另一个变量msg中。请记住,传递的信息将以字节为单位,在上述程序的客户端中,一次传输最多可以接收1024字节(缓冲区大小)。可以指定任何数字,具体取决于传输的信息量。最后,传输的消息应该被解码和打印。现在您知道如何创建客户端-服务器程序,让我们继续看看如何执行它们。Echo客户端-服务器:要执行这些程序,请打开命令提示符,转到您创建客户端和服务器程序的文件夹,然后键入:pyserver.py(这里,server.py是服务器的文件名,您这也可以通过py-3.7server.py完成),服务器将开始运行。要执行客户端,请打开另一个cmd窗口并键入:pyclient.py(这里,client.py是客户端的文件名)输出(服务器):(客户端)让我们将缓冲区大小减小到7以尝试相同编写程序并查看我们得到的输出:输出:如您所见,传输7个字节后连接终止。但这是一个问题,因为您还没有收到完整的消息并且连接已关闭。让我们继续讨论这个问题。多重通信:??为了使连接持续到客户端收到完整信息,可以使用while循环:示例:importsockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((socket.gethostname(),2346))whileTrue:msg=s.recv(7)print(msg.decode("utf-8"))完成后,每次传输将收到7个字节的完整消息。但是这一次,如您所见,连接没有终止,您不知道它何时会发生。除此之外,如果您实际上不知道客户端将从服务器接收到的消息或信息有多大怎么办。在这种情况下,您实际上可以在客户端使用以下代码:Example:complete_info=''whileTrue:msg=s.recv(7)iflen(msg)<=0:breakcomplete_info+=msg.decode("utf-8")print(complete_info)在服务器端,使用close()方法如下所示:clt.close()输出如下所示:消息并在完成后关闭连接之前一次将其打印在两个字节的缓冲区中。传输Python对象:到这里为止,您已经掌握了传输字符串的技巧。然而,Python中的套接字编程也允许您传输Python对象。这些对象可以是从集合到元组再到字典的任何对象。为此,您需要导入Python的pickle模块。Pythonpickle模块:当您在python中实际序列化或反序列化对象时,Pythonpickle模块开始发挥作用。让我们看一个小例子,例子:importpicklemylist=[1,2,'abc']mymsg=pickle.dumps(mylist)print(mymsg)output:b'x80x03]qx00(Kx01Kx02Xx03x00x00x00abcqx01e。如你所见,在上面的程序中,'mylist'是使用pickle模块的dumps()函数进行序列化的,还要注意输出以'b'开头,表示已经转为bytes了,在socket编程中,可以实现这个模块在客户端和服务器之间传输python对象。如何使用pickle模块传递python对象结构?当你将pickle与套接字一起使用时,你可以通过网络传输任何东西。让我们编写服务器端和客户端对应物来传输列表服务器到客户端:服务器端:importsocketimportpicklea=10s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.bind((socket.gethostname(),2133))#bindingtuples.listen(5)while真:clt,adr=s.accept()print(f"Connectionto{adr}established")m={1:"Client",2:"Server"}mymsg=pickle.dumps(m)#themsgwewanttoprintlatermymsg={len(mymsg):{a}}"utf-8")+mymsgclt.send(mymsg)在这里,m是一个字典,它基本上是一个python需要从服务器发送到客户端的对象。这是通过首先使用dumps()序列化对象然后将其转换为字节来完成的。现在我们记下客户端对应的内容:client:importsocketimportpicklea=10s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((socket.gethostname(),2133))whileTrue:complete_info=b''rec_msg=TruewhileTrue:mymsg=s.recv(10)ifrec_msg:print(f"Thelengthofmessage={mymsg[:a]}")x=int(mymsg[:a])rec_msg=Falsecomplete_info+=mymsgiflen(complete_info)-a==x:print("收到完整信息")print(complete_info[a:])m=pickle.loads(complete_info[a:])print(m)rec_msg=Truecomplete_info=b''print(complete_info)第一个while循环将帮助我们跟踪完整的消息(complete_info)和缓冲区接收到的消息(rec_msg)。通过设置rec_来设置消息,然后,当接收到消息时,我所做的就是打印每条消息并在大小为10的缓冲区中接收该消息。这个大小可以是任何值,具体取决于您的个人选择。然后,如果接收到的消息等于完整消息,那么我只是将消息打印为接收到的完整消息,然后使用loads()反序列化消息。上面程序的输出如下:这让我们结束了这篇关于使用套接字编程的文章。希望您能清楚地理解所有概念。点击关注,第一时间了解华为云的新鲜技术~