我想通过TCP与套接字模块将一个移动点的位置发送到服务器上。这个点的位置在每次迭代的时候都会更新。for
循环,并以元组的形式发送。(x, y)
泡菜 dumps
方法。
问题是:在服务器端,我似乎只能从该循环的第一次迭代中获得位置。
在服务器端,我似乎只接收到该循环的第一次迭代的位置。好像所有下面的更新位置都被跳过或在这个过程中丢失了。
我不能确定这种行为背后的原因是什么,但我打赌是我在服务器端没有正确设置。我怀疑数据完全被发送,但在接收时没有得到充分的处理,因为我可能在socket模块上犯了一些错误(我对网络接口的世界完全陌生)。
代码:--客户端----------。
--客户端--
#Python3.7
import socket
import pickle
import math
HOST = "127.0.0.1"
PORT = 12000
den = 20
rad = 100
theta = math.tau / den
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT)) #connect to server
for step in range(1000):
i = step%den
x = math.cos(i*theta) * rad
y = math.sin(i*theta) * rad
data = pickle.dumps((x, y), protocol=0)
sock.sendall(data)
--服务器端--
#Jython2.7
import pickle
import socket
HOST = "127.0.0.1"
PORT = 12000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while True:
connection, address = s.accept()
if connection:
data = connection.recv(4096)
print(pickle.loads(data)) # <-- only print once (first location)
你需要把connection, address = s.accept()放在while循环之外,否则你的服务器每次都会等待一个新的连接。
你的接收数据的方式也有问题,你需要将连接,地址=s.accept()放在while循环之外,否则你的服务器每次都会等待新的连接。connection.recv(4096)
在接收到完整的 "数据 "消息时,s.accept()会返回0到4096之间的任何字节数,而不是每次都返回。为了处理这个问题,你可以在发送json之前发送一个头,指示应该接收多少数据通过添加一个头,你将确保你发送的数据消息将被正确接收。
这个例子中的头是一个四个字节的int,表示数据的大小。服务器
import pickle
import socket
import struct
HEADER_SIZE = 4
HOST = "127.0.0.1"
PORT = 12000
def receive(nb_bytes, conn):
# Ensure that exactly the desired amount of bytes is received
received = bytearray()
while len(received) < nb_bytes:
received += conn.recv(nb_bytes - len(received))
return received
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
connection, address = s.accept()
while True:
# receive header
header = receive(HEADER_SIZE, connection)
data_size = struct.unpack(">i", header)[0]
# receive data
data = receive(data_size, connection)
print(pickle.loads(data))
客户
import socket
import pickle
import math
HEADER_SIZE = 4
HOST = "127.0.0.1"
PORT = 12000
den = 20
rad = 100
theta = math.tau / den
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT)) #connect to server
for step in range(1000):
i = step%den
x = math.cos(i*theta) * rad
y = math.sin(i*theta) * rad
data = pickle.dumps((x, y), protocol=0)
# compute header by taking the byte representation of the int
header = len(data).to_bytes(HEADER_SIZE, byteorder ='big')
sock.sendall(header + data)
希望能帮到你