python socket并行收发
python socket parallel sending and receiving
我正在开发一个简单的项目,该项目将“服务器”cpu 和 ram 使用情况与 pstuil 库一起发送给客户端,但我遇到了困难。简而言之,我的问题是我无法验证客户端收到的数据。
我的服务器代码:
# Import Section
import socket
import threading
import psutil
import time
# TCP Socket Connection for server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 6767))
server.listen()
client, address = server.accept()
# Functions
def cpu():
while True:
cpu_usage = str(psutil.cpu_percent(1))
client.send(cpu_usage.encode("ascii"))
def ram():
while True:
time.sleep(1)
ram_usage = str(psutil.virtual_memory()[2])
client.send(ram_usage.encode("ascii"))
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
我的客户代码:
# Import Section
import socket
import threading
import time
# TCP Socket Connection for server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect(("127.0.0.1", 6767))
# Functions
def cpu():
while True:
server.send("cpu".encode("ascii"))
cpu_usage = server.recv(1024).decode("ascii")
print(f"cpu usage is {cpu_usage}")
time.sleep(1)
def ram():
while True:
server.send("ram".encode("ascii"))
ram_usage = server.recv(1024).decode("ascii")
print(f"ram usage is {ram_usage}")
time.sleep(1)
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
我的预期输出:
cpu usage is cpu_usage
ram usage is ram_usage
example:
cpu usage is 0.3
ram usage is 14.7
实际输出:
randomly
cpu usage is ram_usage
ram usage is cpu_usage
or
cpu usage is cpu_usage
ram usage is ram_usage
example:
cpu_usage is 14.7
ram usage is 0.3
cpu usage is 0.3
ram usage is 14.7
好像不是在一行中发送的。一个答案是通过服务器发送所有数据,但我只想发送原始 cpu 或 ram 数据并在客户端代码中对它们进行排序。
感谢您提供代码,我能够轻松地在我的 VM 上重现该问题。
简短回答:您将 RAM 和 CPU 数据包发送到同一个套接字,当您调用 server.recv() 时,您可以获取 RAM或 CPU 数据包,无论您调用 recv() 时使用的函数如何。
更多信息:虽然 TCP 保证了数据包的顺序,但是当为每个功能使用不同的线程时,它们可能会失去同步,以至于您会到达在服务器端或客户端调用 ram() (或反之亦然)之前连续两次调用 cpu() 的点。您甚至可以看到这种情况的发生,因为屏幕上的打印不一致,有时会连续打印 CPU 或 RAM 两次。
有几种方法可以解决这个问题。通过为每个功能使用不同的套接字,您可以确保永远不会混淆(参见下面的代码)。另一种选择是仅 运行 在客户端请求时在服务器端进行测量。我不确定这是否是您打算在客户端代码中执行的操作:
在cpu():
cpu_server.send("cpu".encode("ascii"))
在 ram():
ram_server.send("ram".encode("ascii"))
我可以看到这些数据包在 tcpdump 中发出,但我不认为它们有任何作用,因为服务器没有从套接字中获取它们。
您的每次测量套接字代码(随意use/modify):
server.py:
# Import Section
import socket
import threading
import psutil
import time
# Functions
def cpu():
# TCP Socket Connection for CPU server
cpu_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cpu_server.bind(("127.0.0.1", 6767))
cpu_server.listen()
cpu_client, cpu_address = cpu_server.accept()
while True:
cpu_usage = str(psutil.cpu_percent(1))
cpu_client.send(cpu_usage.encode("ascii"))
def ram():
# TCP Socket Connection for RAM server
ram_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ram_server.bind(("127.0.0.1", 6768))
ram_server.listen()
ram_client, ram_address = ram_server.accept()
while True:
time.sleep(1)
ram_usage = str(psutil.virtual_memory()[2])
ram_client.send(ram_usage.encode("ascii"))
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
client.py:
# Import Section
import socket
import threading
import time
# Functions
def cpu():
# TCP Socket Connection for CPU server
cpu_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cpu_server.connect(("127.0.0.1", 6767))
while True:
cpu_usage = cpu_server.recv(1024).decode("ascii")
print(f"cpu usage is {cpu_usage}")
time.sleep(1)
def ram():
# TCP Socket Connection for RAM server
ram_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ram_server.connect(("127.0.0.1", 6768))
while True:
ram_usage = ram_server.recv(1024).decode("ascii")
print(f"ram usage is {ram_usage}")
time.sleep(1)
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
请注意 - 由于操作阻塞且响应时间太慢,我不得不在线程内进行 TCP 连接。当我尝试从主进程连接时,客户端出现问题,因为当它在第二个套接字上调用 connect() 时,服务器端可能尚未侦听其第二个套接字。
我正在开发一个简单的项目,该项目将“服务器”cpu 和 ram 使用情况与 pstuil 库一起发送给客户端,但我遇到了困难。简而言之,我的问题是我无法验证客户端收到的数据。
我的服务器代码:
# Import Section
import socket
import threading
import psutil
import time
# TCP Socket Connection for server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 6767))
server.listen()
client, address = server.accept()
# Functions
def cpu():
while True:
cpu_usage = str(psutil.cpu_percent(1))
client.send(cpu_usage.encode("ascii"))
def ram():
while True:
time.sleep(1)
ram_usage = str(psutil.virtual_memory()[2])
client.send(ram_usage.encode("ascii"))
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
我的客户代码:
# Import Section
import socket
import threading
import time
# TCP Socket Connection for server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect(("127.0.0.1", 6767))
# Functions
def cpu():
while True:
server.send("cpu".encode("ascii"))
cpu_usage = server.recv(1024).decode("ascii")
print(f"cpu usage is {cpu_usage}")
time.sleep(1)
def ram():
while True:
server.send("ram".encode("ascii"))
ram_usage = server.recv(1024).decode("ascii")
print(f"ram usage is {ram_usage}")
time.sleep(1)
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
我的预期输出:
cpu usage is cpu_usage
ram usage is ram_usage
example:
cpu usage is 0.3
ram usage is 14.7
实际输出:
randomly
cpu usage is ram_usage
ram usage is cpu_usage
or
cpu usage is cpu_usage
ram usage is ram_usage
example:
cpu_usage is 14.7
ram usage is 0.3
cpu usage is 0.3
ram usage is 14.7
好像不是在一行中发送的。一个答案是通过服务器发送所有数据,但我只想发送原始 cpu 或 ram 数据并在客户端代码中对它们进行排序。
感谢您提供代码,我能够轻松地在我的 VM 上重现该问题。
简短回答:您将 RAM 和 CPU 数据包发送到同一个套接字,当您调用 server.recv() 时,您可以获取 RAM或 CPU 数据包,无论您调用 recv() 时使用的函数如何。
更多信息:虽然 TCP 保证了数据包的顺序,但是当为每个功能使用不同的线程时,它们可能会失去同步,以至于您会到达在服务器端或客户端调用 ram() (或反之亦然)之前连续两次调用 cpu() 的点。您甚至可以看到这种情况的发生,因为屏幕上的打印不一致,有时会连续打印 CPU 或 RAM 两次。
有几种方法可以解决这个问题。通过为每个功能使用不同的套接字,您可以确保永远不会混淆(参见下面的代码)。另一种选择是仅 运行 在客户端请求时在服务器端进行测量。我不确定这是否是您打算在客户端代码中执行的操作:
在cpu():
cpu_server.send("cpu".encode("ascii"))
在 ram():
ram_server.send("ram".encode("ascii"))
我可以看到这些数据包在 tcpdump 中发出,但我不认为它们有任何作用,因为服务器没有从套接字中获取它们。
您的每次测量套接字代码(随意use/modify):
server.py:
# Import Section
import socket
import threading
import psutil
import time
# Functions
def cpu():
# TCP Socket Connection for CPU server
cpu_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cpu_server.bind(("127.0.0.1", 6767))
cpu_server.listen()
cpu_client, cpu_address = cpu_server.accept()
while True:
cpu_usage = str(psutil.cpu_percent(1))
cpu_client.send(cpu_usage.encode("ascii"))
def ram():
# TCP Socket Connection for RAM server
ram_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ram_server.bind(("127.0.0.1", 6768))
ram_server.listen()
ram_client, ram_address = ram_server.accept()
while True:
time.sleep(1)
ram_usage = str(psutil.virtual_memory()[2])
ram_client.send(ram_usage.encode("ascii"))
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
client.py:
# Import Section
import socket
import threading
import time
# Functions
def cpu():
# TCP Socket Connection for CPU server
cpu_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cpu_server.connect(("127.0.0.1", 6767))
while True:
cpu_usage = cpu_server.recv(1024).decode("ascii")
print(f"cpu usage is {cpu_usage}")
time.sleep(1)
def ram():
# TCP Socket Connection for RAM server
ram_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ram_server.connect(("127.0.0.1", 6768))
while True:
ram_usage = ram_server.recv(1024).decode("ascii")
print(f"ram usage is {ram_usage}")
time.sleep(1)
# Threads
t1 = threading.Thread(target=cpu).start()
t2 = threading.Thread(target=ram).start()
请注意 - 由于操作阻塞且响应时间太慢,我不得不在线程内进行 TCP 连接。当我尝试从主进程连接时,客户端出现问题,因为当它在第二个套接字上调用 connect() 时,服务器端可能尚未侦听其第二个套接字。