Python 套接字 Accept 超时

180 篇文章 5 订阅
5 篇文章 0 订阅
本文介绍了Python中套接字的超时功能,解决无限期等待连接的问题。套接字的accept()、settimeout()和setdefaulttimeout()方法在控制连接超时中起关键作用。通过示例展示了如何设置和处理套接字接受超时。
摘要由CSDN通过智能技术生成

套接字是网络通信的基本构建块。 每当两个网络实体需要传输数据时,就会打开一个套接字。

这些套接字在会话期间保持连接。 但有时,在 Python 中使用套接字时,您可能会等待很长时间,而另一端仍然接受套接字连接。

本文讨论了 Python 中套接字的超时功能,该功能对于缓解无限期等待套接字接受的问题是必要的。


套接字接受、拒绝和超时

每当您尝试使用 Python 脚本建立与服务器的连接时,您都需要打开一个套接字连接。 此套接字连接充当在客户端和服务器之间传输数据的隧道。

在打开socket的过程中,有三种场景。

  1. Socket Accept:当socket打开成功,此时服务端和客户端已经建立连接,可以收发数据,我们称之为socket accept。 这个场景就是打开一个socket的最终目的。
  2. Socket reject:假设您打开了一个套接字但传递了一些不同的参数,忘记传递参数或没有正确遵循打开套接字的过程; 你会得到拒绝。 这意味着无法建立发送和接收数据的连接。
  3. Socket Accept 超时:这是一个重要但被忽视的场景。 有时当您尝试打开一个套接字时,您可能不会从另一端得到任何响应。

    因此,您将永远等待。 这是一种不受欢迎的情况,因为您想关闭当前请求并尝试另一个请求,而不是永远等待。

    超时选项允许您设置最长等待时间以使您的请求被另一方接受。 超过时间限制后,将引发错误。


套接字方法及其在 Python 中的使用

Python 有一个名为 socket 的内置库,您需要导入它才能使用套接字连接。 让我们看看套接字库的一些重要方法。

  1. accept():顾名思义,accept() 方法接受来自另一方的传入套接字请求。 此方法返回一个套接字连接,您可以使用它在连接的实体之间传输数据。
  2. bind():此方法将套接字连接绑定或附加到地址。 如果您想使用套接字,则必须调用此方法。

    bind() 方法接受一个 IP 地址元组和它绑定套接字的端口。

  3. listen():这是一个服务器端方法,它使服务器能够接受套接字以在连接之间传输数据。
  4. connect():此方法接受一个地址作为参数。 然后它在该地址连接远程套接字。
  5. settimeout():此方法接受一个非零数字作为引发 TimeoutError 之前等待的秒数。 此方法对于缓解无限等待时间的问题很重要。
  6. setdefaulttimeout():如果您使用多个套接字连接并希望为每个连接设置相同的超时限制,那么这是您的首选方法。 它接受秒数作为参数,并将其作为等待超时限制应用于所有新的套接字连接。

Python 中的套接字接受超时示例

让我们在 Python 代码的帮助下看一个套接字接受超时的例子。 对于此示例,我们需要编写两个 Python 脚本,一个用于服务器,另一个用于客户端。

我们将看到三种不同的场景,如下所述。

  1. 第一种情况是没有设置超时限制。 在这种情况下,客户将继续等待。

    请注意,根据您的操作系统,请求可能会在一段时间后自动拒绝。

  2. 第二种情况是我们使用 settimeout() 方法设置超时限制。 在这种情况下,您将在设置的限制后得到 TimeoutError。
  3. 在第三种情况下,我们将使用 setdefaulttimeout() 方法来设置超时限制。

下面我们一一看看上面三种情况的代码。

未设置超时限制时 Python 中的套接字接受超时

服务器端脚本:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
     s.bind(('', 1717))

客户端脚本

import socket

 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
     s.connect(('127.0.0.1', 1717))

您在服务器端看不到 listen() 方法。 因此,服务器没有响应,客户端正在等待。

设置超时时Python中的套接字接受超时

在这种情况下,您会看到客户端在超过超时时间后中止操作并引发 TimeoutError。

服务器端:

import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(('', 1717))

客户端脚本

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
     s.settimeout(3)
     s.connect(('127.0.0.1', 1717))

在这种情况下,会引发 Python 套接字 TimeoutError。 请注意,套接字的行为可能因平台而异。

在 Linux 机器上,套接字抛出 ConnectionRefusedError: [Errno 111] Connection refused 错误,直到您不接受服务器端的套接字。


在 Python 中为每个套接字设置默认超时

此方法将为所有新套接字设置相同的默认超时。 这样,您可以通过为每个套接字单独设置超时来节省时间和麻烦。

服务器端:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind(('', 1717))

客户端:

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    socket.setdefaulttimeout(3)
    s.connect(('127.0.0.1', 1717))

请注意 ,对于 setdefaulttimeout() ,您必须直接使用套接字类而不是对象,因为它为所有线程设置超时。


总结

套接字超时是 Python 套接字编程的一个重要方面。 如果您不处理超时,您可能会让您的客户端永远等待套接字。

或者在其他情况下,根据您的环境实现,它可能会引发错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实验名称:流式套接字程序设计 实验目的:通过实验学习并掌握流式套接字的使用方法及其在网络通信中的应用。 实验内容: 1. 编写一个简单的客户端程序,连接到指定的服务器,并向服务器发送一条消息。 2. 编写一个简单的服务器程序,监听指定的端口号,接收客户端发送的消息,并将消息打印输出到控制台上。 3. 实现客户端和服务器之间的双向通信,即客户端可以向服务器发送消息,服务器也可以向客户端发送消息。 实验步骤: 1. 编写客户端程序 ```python import socket # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 指定服务器的IP地址和端口号 server_address = ('127.0.0.1', 8888) # 连接到服务器 client_socket.connect(server_address) # 向服务器发送一条消息 message = 'Hello, Server!' client_socket.sendall(message.encode()) # 接收服务器的响应并打印输出 data = client_socket.recv(1024) print('Received from server:', data.decode()) # 关闭连接 client_socket.close() ``` 2. 编写服务器程序 ```python import socket # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 指定监听的端口号 server_address = ('127.0.0.1', 8888) server_socket.bind(server_address) # 开始监听连接 server_socket.listen(1) print('Listening on', server_address) # 接受客户端的连接请求 client_socket, client_address = server_socket.accept() print('Connected by', client_address) # 接收客户端发送的消息并打印输出 data = client_socket.recv(1024) print('Received from client:', data.decode()) # 向客户端发送一条消息 message = 'Hello, Client!' client_socket.sendall(message.encode()) # 关闭连接 client_socket.close() server_socket.close() ``` 3. 实现客户端和服务器之间的双向通信 客户端程序: ```python import socket # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 指定服务器的IP地址和端口号 server_address = ('127.0.0.1', 8888) # 连接到服务器 client_socket.connect(server_address) while True: # 从控制台输入消息并发送给服务器 message = input('Input message to server:') client_socket.sendall(message.encode()) # 接收服务器的响应并打印输出 data = client_socket.recv(1024) print('Received from server:', data.decode()) # 关闭连接 client_socket.close() ``` 服务器程序: ```python import socket # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 指定监听的端口号 server_address = ('127.0.0.1', 8888) server_socket.bind(server_address) # 开始监听连接 server_socket.listen(1) print('Listening on', server_address) # 接受客户端的连接请求 client_socket, client_address = server_socket.accept() print('Connected by', client_address) while True: # 接收客户端发送的消息并打印输出 data = client_socket.recv(1024) print('Received from client:', data.decode()) # 从控制台输入消息并发送给客户端 message = input('Input message to client:') client_socket.sendall(message.encode()) # 关闭连接 client_socket.close() server_socket.close() ``` 实验结果: 经过实验,我们成功地编写了一个简单的流式套接字程序,实现了客户端与服务器之间的单向和双向通信,并通过控制台输出了相应的消息。 实验结论: 流式套接字是一种在网络上进行数据传输的工具,通过它可以在不同的计算机之间进行数据传输。我们可以使用套接字函数库来实现Socket连接的建立、数据的传输等功能。在进行网络通信时,需要设置超时时间,避免出现因网络延迟等问题导致程序卡死的情况。通过实验,我们掌握了流式套接字的使用方法及其在网络通信中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迹忆客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值