如何接收和处理多个TCP流套接字?

问题描述 投票:0回答:1

我想通过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)
python sockets tcp pickle
1个回答
2
投票

你需要把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)

希望能帮到你

© www.soinside.com 2019 - 2024. All rights reserved.