如何监视TCP端口的数据包并在没有收到时超时?

时间:2015-03-13 03:33:03

标签: python network-programming

我正在创建一个使用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()

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

1 个答案:

答案 0 :(得分:0)

首先,这一行:

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"并处理回应。