【问题标题】:How can I monitor a TCP port for packets and timeout if none is received?如果没有收到数据包,如何监控 TCP 端口的数据包和超时?
【发布时间】:2015-03-13 15:45:14
【问题描述】:

我正在使用 python 创建一个测试客户端来测试我的服务器。它将 TCP 数据包发送到服务器,应该在同一 TCP 连接中向客户端发送回 1 个响应。如果它没有发送任何响应,或者发送超过 1 个响应,那么我在服务器代码中存在错误。

我想要做的是监视 TCP 端口的响应消息并将它们打印出来。如果没有响应,脚本应该在超时后继续执行。

以下是相关代码:

import socket
import time
import multiprocessing


def get_response(response_stream, response_buffer_size):
    response_count = 1
    while True:
        response = response_stream.recv(response_buffer_size).decode()
        print("[response]", response_count, ":", response)
        response_count += 1

TCP_IP = '192.168.1.101'
TCP_PORT = 12345
BUFFER_SIZE = 1024
MESSAGE = b"Bazinga!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE.encode())

print("Message sent.")

p = multiprocessing.Process(target = get_response(s,BUFFER_SIZE))
p.start()
p.join(3)

if p.is_alive():
    print("Killing thread ...")
    p.terminate()
    p.join()

s.close()
print("Socket closed.")

所以事实证明永远不会到达p.join(3),因为代码被困在get_response 的这一行:response = response_stream.recv(response_buffer_size).decode()

脚本将一直在那里等待解码下一个数据包,因此脚本永远不会正确终止。我做错了什么?

【问题讨论】:

  • 您使用的是 windows 还是 unix?您可以使用一个仅限于 unix 的功能。
  • 另外,什么版本的 Python?
  • 客户端是python 3,在windows上。在 linux 上运行相同代码的能力将是一个奖励。

标签: python network-programming


【解决方案1】:

首先,这一行:

p = multiprocessing.Process(target = get_response(s,BUFFER_SIZE))

实际上是在主线程上调用get_response。因为,您没有像应该那样传递函数名称,而是调用函数并传递 target 参数,即调用的结果。

你想要的

p = multiprocessing.Process(target=get_response, args=(s,BUFFER_SIZE))

但这行不通!您不能轻易地将套接字传递给不同的进程。有一些方法可以使用管道,但该实现仅适用于 Windows 上的 Unix 或 Python3。

所以考虑一下我在下面列出的不同方法。

第三,您可能希望在子进程函数中添加一些打破无限循环的内容。我添加了一行来检查recv是否返回了一个空字符串,你可以根据自己的喜好修改它。

考虑:

import socket
import time
import multiprocessing


def worker(tcp_ip, tcp_port, response_buffer_size):
    MESSAGE = b"Bazinga!"

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((tcp_ip, tcp_port))
    s.send(MESSAGE.encode())
    print("Message sent.")

    response_count = 1
    while True:
        response = s.recv(response_buffer_size).decode()
        if len(response) == 0: break
        print("[response]", response_count, ":", response)
        response_count += 1
    # If we got here, the connection was closed
    s.close()
    print("Socket closed.")


if __name__ == "__main__":
    TCP_IP = '192.168.1.10'
    TCP_PORT = 12345
    BUFFER_SIZE = 1024

    p = multiprocessing.Process(target=worker, args=(TCP_IP, TCP_PORT, BUFFER_SIZE))
    p.start()
    p.join(3)

    if p.is_alive():
        print("Killing thread ...")
        p.terminate()
        p.join()
        print("Thread terminated.")

    print("Goodbye.")

在这里,我们将所有套接字活动放在工作线程中。它拥有并打开套接字,发送“Bazinga”并处理响应。

【讨论】:

  • 测试客户端应该监视单个 TCP 连接 N 秒,以获取任意数量的响应。超过 1 个响应意味着服务器做错了。
  • 你好,你能分享一下如何用管道实现类似的效果吗?
猜你喜欢
  • 2013-12-25
  • 2012-09-19
  • 1970-01-01
  • 2015-08-28
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 2023-02-08
相关资源
最近更新 更多