我正在创建一个使用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()
。
脚本将始终在那里等待解码下一个数据包,因此脚本永远不会正常终止。我做错了什么?
答案 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"并处理回应。