Python中的插座编程:客户端,服务器和点对点库
#教程 #python #chat #socket

在本教程中,您将学习如何使用Python套接字编程和套接字API在客户端和服务器之间交换数据。后来,本教程将讨论使用托管提供商在两个或多个Python客户端之间直接交换数据。可以在GitHub repository中找到本教程中使用的源代码。

套接字编程连接两个插座(客户端套接字和一个服务器套接字),并允许他们实时进行双向通信。直接插座连接可以使所有实时应用程序受益,因为可以随时发送或接收数据。

设置环境

您将需要安装在计算机上的Python version 3.x的稳定版本。如果您是Windows用户,则可以选择将Python添加到您的路径中。

您还需要一个代码编辑器与本教程一起遵循。 Visual Studio Code是一款流行的开源和免费代码编辑器,支持包括Python在内的许多语言和框架。 VSCODE还支持Python的扩展,以帮助代码完成和调试。

构建并运行Python插座应用程序

让我们使用python构建一个直接的套接字应用程序。 Python提供了一个本机socket class(套接字模块),因此开发人员不需要依赖外部库。首先设置Python插座客户端和服务器:

Python socket stack

在项目目录中创建文件client.py。要使用插座,请导入Python套接字库,并创建一个连接到指定IP地址的新套接字对象(在这种情况下,端口号8080上的Localhost,但您可以选择任何IPv4地址)。创建到套接字服务器的新连接,将数据发送到TCP服务器,然后关闭套接字连接。

您的client.py文件应该看起来像这样:

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('0.0.0.0', 8080))
client.send("I am CLIENT\n".encode())
from_server = client.recv(4096)
client.close()
print (from_server.decode())

您将需要套接字服务器来收听客户端的传入连接和消息。创建文件server.py并添加以下内容:

import socket
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv.bind(('0.0.0.0', 8080))
serv.listen(5)
while True:
  conn, addr = serv.accept()
  from_client = ''
  while True:
    data = conn.recv(4096)
    if not data: break
    from_client += data.decode('utf8')
    print (from_client)
    conn.send("I am SERVER\n".encode())
  conn.close()
  print ('client disconnected and shutdown')

Server.py将套接字对象绑定到端口8080上的主机名(localhost),并不断聆听新客户端连接。当客户端连接到此地址时,服务器接受连接并读取任何数据。一旦数据从客户端成功读取,服务器就会提供数据响应,此时客户端终止了连接。

自己对此进行测试,请同时打开两个终端窗口。在一个窗口中,运行:

python3 server.py

在第二个窗口中,运行:

python3 client.py

请注意,服务器继续运行,每次运行客户端并附加任何新输出时都会建立新连接。

客户端将向服务器发送“我是客户端”字符串并等待回复。服务器将读取客户端的消息,将其输出到终端,然后向客户端发送回复。

Python Socket Example

使用PubNub在Python中编程

到目前为止,本教程涵盖了服务器和客户端之间的交换消息,但是如果您需要直接在Python客户端进行通信怎么办?

直接在两个或多个客户端设备之间发送数据很棘手,因为随着设备数量的增加,您会遇到许多缩放和安全考虑。客户端服务器体系结构用于适度和管理您的客户对客户通信。如果您没有Web服务器,或者担心服务器扩展以满足应用程序的需求,则应选择托管的实时通信解决方案,例如PubNub。 PubNub是一个全球分布式和可扩展的云平台,因此您不必担心部署和维护服务器。 PubNub的跨平台SDK,包括Python,可以识别用户并将消息发送到特定的渠道,只有订阅的客户才会收到。

客户到客户的Python套筒编程

那么,如何使用PubNub编写的简单应用程序如何直接在两个客户之间交换消息?必须了解,尽管PubNub使用发布和订阅架构(Pub/sub)在端点之间发送和接收双向消息,但它仍然在幕后使用插座。 PubNub为您提供了插座通信的好处,而不必担心Python网络编程的详细信息并保持客户之间的始终连接,而不论操作系统如何。

要将PubNub集成到项目中,请将PubNub软件包与终端中的PIP安装;这将使您可以使用PubNub Python SDK并与PubNub基础架构进行通信。

pip3 install 'pubnub>=7.1.0'

您将需要创建两个客户端,以通过PubNub网络连接和通信。创建一个文件pn_client_1.py并添加以下代码:

from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNStatusCategory
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
import time
import os
pnconfig = PNConfiguration()
userId = os.path.basename(__file__)
pnconfig.publish_key = 'demo'
pnconfig.subscribe_key = 'demo'
pnconfig.user_id = userId
pnconfig.ssl = True
pubnub = PubNub(pnconfig)
def my_publish_callback(envelope, status):
  # Check whether request successfully completed or not
  if not status.is_error():
    pass
class MySubscribeCallback(SubscribeCallback):
  def presence(self, pubnub, presence):
    pass
  def status(self, pubnub, status):
    pass
  def message(self, pubnub, message):
    if message.publisher == userId : return
    print ("from device " + message.publisher + ": " + message.message)
pubnub.add_listener(MySubscribeCallback())
pubnub.subscribe().channels("chan-1").execute()
## publish a message
while True:
  msg = input("")
  if msg == 'exit': os._exit(1)
  pubnub.publish().channel("chan-1").message(str(msg)).pn_async(my_publish_callback)

创建文件pn_client_2.py,并添加与pn_client_1.py

的相同代码

上面的代码使用“演示”键,但是您可以免费获得自定义的PubNub keys

同时在两个不同的终端窗口中同时运行pn_client_1.pypn_client_2.py

python3 pn_client_1.py
python3 pn_client_2.py

每个客户端将其与PubNub网络的连接初始化,并在将新消息发布到chan-1频道时订阅以接收新消息。您可以将其视为通过Python中的TCP插座发送数据;在幕后,PubNub正在为您创建和管理套接字,并将您的消息路由到所有正在聆听的客户的客户。一旦远程客户端收到消息,将在命令行上显示收到的消息。

Python PubNub example

那就是一切!有关使用PubNub开发的更多信息,请查看其tutorialsdemos的范围。另外,请查看PubNub interactive live tour,以了解平台如何为应用程序提供实时交互性。 PubNub支持TCP和UDP Datagram通信,以及Linux,Unix和Windows。