Python 的 socket 模块:通过客户端访问socket服务器

举报
Tiamo_T 发表于 2021/10/24 11:48:35 2021/10/24
【摘要】 这篇文章的目的是解释如何使用 Python 创建一个简单的socket服务器并通过客户端访问它。Python 是一种非常易于使用的语言,因此,像往常一样,我们只需调用几个函数就可以设置我们的服务器。编码我们需要做的第一件事是导入 Python 的 socket 模块,它将公开一个非常易于使用的 API,允许我们设置一个 socket 服务器。该模块默认随 Python 一起提供,因此不需要安...

这篇文章的目的是解释如何使用 Python 创建一个简单的socket服务器并通过客户端访问它。

Python 是一种非常易于使用的语言,因此,像往常一样,我们只需调用几个函数就可以设置我们的服务器。
python

编码

我们需要做的第一件事是导入 Python 的 socket 模块,它将公开一个非常易于使用的 API,允许我们设置一个 socket 服务器。该模块默认随 Python 一起提供,因此不需要安装额外的数据包。

import socket

接下来我们将创建一个socket类的对象。为此,我们需要调用在导入的套接字模块中定义的类构造函数。

我们将调用无参数构造函数,它将使用默认值来创建对象,但您可以在此处检查可用选项和可能的参数。

s = socket.socket()

接下来,我们需要将套接字绑定到一个地址,该地址将由服务器将侦听的 IP 和端口组成。

为此,我们只需要在我们刚刚创建的套接字对象上调用bind方法。作为输入,它会收到一个元组与IP(字符串)和端口(如数字)。

在我们的例子中,由于我们要在同一台机器上执行测试,我们可以使用环回 IP 127.0.0.1。我将使用端口 8090,但您可以尝试另一个端口,只要它尚未在您的机器中使用。

s.bind(('127.0.0.1', 8090))

执行绑定后,我们将启用我们的套接字服务器开始侦听传入的连接。我们通过调用socket 对象上的listen方法来做到这一点。

此方法接收系统在拒绝新连接之前允许的未接受连接数作为输入 [1]。由于我们每次都会对单个客户端进行非常简单的测试,因此我们可以将值 0 传递给它。

s.listen(0)

现在我们已经完成了所有的服务器设置,我们通过调用socket 对象上的accept方法开始接收实际的连接。此调用将阻止执行,直到新客户端连接到服务器。

当客户端连接时,此方法返回一对新的套接字对象和连接客户端的地址 [2]。这个新的套接字对象可用于发送和接收数据 [2],因为套接字是双向的。

我们将在无限循环中执行此调用和剩余的客户端处理,因此我们可以在客户端断开连接后保持服务器工作。

while True:
    client, addr = s.accept()
    #Client handling code

在上一次调用之后,我们可以开始与客户端交换数据。在这个例子中,我们将简单地从他那里接收内容,但如前所述,套接字是双向的,我们也可以向它发送数据。

数据的接收也将在无限循环中完成,我们只会在客户端断开连接时中断。

要接收数据,我们只需调用客户端套接字对象(由 accept 方法返回的对象)上的recv方法。

在 Python 3.x(这是我在本篇中使用的那个)中,recv 方法将来自客户端的数据作为字节对象返回 [3]。但是,在 Python 2.x 中,数据以字符串形式返回 [4]。
作为输入,我们需要将一次接收的最大字节数传递给 recv 方法 [3]。但是请注意,如果客户端发送的数据多于指定的值,它不会丢失,并且可以通过对 recv 方法的其他调用来检索。

需要考虑的一件重要事情是这个 recv 方法调用也是阻塞的。因此,执行将阻塞,直到一些数据从客户端到达。

如果客户端断开连接,recv 方法将返回一个空字节对象,这将是我们中断读取循环的停止条件。

因此,在调用 recv 方法之后,我们将检查 bytes 对象的长度。如果它等于零,我们就中断读取循环。否则,我们打印接收到的内容。

while True:
 
    client, addr = s.accept()
 
    while True:
        content = client.recv(32)
 
        if len(content) ==0:
           break
 
        else:
            print(content)

中断读取循环后,我们调用客户端socket对象的close方法来释放资源。

client.close()

最终代码如下所示。

import socket
 
s = socket.socket()         
 
s.bind(('127.0.0.1', 8090 ))
s.listen(0)                 
 
while True:
 
    client, addr = s.accept()
 
    while True:
        content = client.recv(32)
 
        if len(content) ==0:
           break
 
        else:
            print(content)
 
    print("Closing connection")
    client.close()


测试代码

为了测试代码,我们也可以用 Python 开发一个非常简单的套接字客户端,这很容易做到。尽管如此,为了简化它,我们将使用我们的 Web 浏览器作为客户端来联系套接字服务器。

因此,在运行 Python 程序后,打开您选择的 Web 浏览器并在地址栏中键入以下内容(如果您尚未使用端口 8090,请自行更改此值):

http://127.0.0.1:8090

您的 Web 浏览器应该挂起等待答案,但如果您返回 Python 提示符,您应该会得到类似于图 1 的输出,其中显示了一些数据正在打印。

图 1 – Python 程序的输出。

上图显示了浏览器在发出 HTTP 请求时发送给服务器的内容。这表明我们每天在 Internet 中使用的 HTTP 协议是建立在套接字之上的,这就是我们可以使用 Web 浏览器访问我们的套接字服务器的原因。

由于我们的套接字服务器级别非常低,并且不知道 HTTP 层是如何工作的,因此它不会向浏览器返回任何答案,这就是它会挂起的原因。

如果您返回浏览器并关闭它,那么服务器应该检测到它,并且在释放资源后它应该打印“正在关闭连接”消息,如图 1 中突出显示的。

之后,服务器应该返回侦听新连接,您可以从 Web 浏览器再次连接到它。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。