Python套接字TCP截断消息
我有一个通信系统,每个用户都有一个tcp服务器和客户端。我必须使用计算机来测试我的系统。其思想是一个用户向另一个用户请求信息,然后接收该信息。但是当我从1号计算机到2号计算机做这件事的时候,它是工作的,但是另一种方式是不工作的,信息被截断了。以下是相关代码:Python套接字TCP截断消息,python,sockets,tcp,Python,Sockets,Tcp,我有一个通信系统,每个用户都有一个tcp服务器和客户端。我必须使用计算机来测试我的系统。其思想是一个用户向另一个用户请求信息,然后接收该信息。但是当我从1号计算机到2号计算机做这件事的时候,它是工作的,但是另一种方式是不工作的,信息被截断了。以下是相关代码: server.py def handle_client(conn, addr): connected = True while connected: msg_length = conn.recv(HEADER).decode(FO
server.py
def handle_client(conn, addr):
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
elif msg == "REQBLOCKCHAIN":
print(f"Blockchain request from {addr}")
addr_s = addr[0]
print(addr_s)
conn.send("Chain successfully requested.".encode(FORMAT))
send_chain(addr_s)
elif msg == "BLOCKCHAIN":
print(f"Blockchain received from {addr}")
print(threading.active_count())
chain_length = conn.recv(HEADER).decode(FORMAT)
if chain_length:
chain_length = int(chain_length)
chain_recv = conn.recv(chain_length)
print("b")
print(chain_recv)
chain = chain_recv.decode(FORMAT)
print(chain_length)
print(chain)
print(len(chain_recv))
chain_dict = json.loads(fix_text(chain))
print(chain_dict[-1])
chain_is_valid = is_chain_valid(chain_dict)
if chain_is_valid:
try:
with open("data/blockchain.json") as og_chain_file:
og_chain = json.load(og_chain_file)
if og_chain == chain_dict:
conn.send("Same".encode(FORMAT))
return "Same"
else:
if og_chain[-1]['index'] < chain_dict[-1]['index']:
with open("data/blockchain.json", "w") as chain_file:
json.dump(chain_dict, chain_file)
conn.send("Chain successfully broadcasted.".encode(FORMAT))
return "Blockchian updated"
else:
conn.send("Same or newer".encode(FORMAT))
return "Same or newer"
except FileNotFoundError:
conn.send("Blockchain data file missing".encode(FORMAT))
return "Blockchain data file missing"
else:
err = {'message' : 'Received chain is not valid !',
'ip_sender': addr[0]}
conn.send(json.dumps(err).encode(FORMAT))
return err
conn.close()
def req_blockchain(addr):
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
ADDR = (addr, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
msg_length = len("REQBLOCKCHAIN")
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send("REQBLOCKCHAIN".encode(FORMAT))
print(client.recv(2048).decode(FORMAT))
def send_chain( addr):
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
ADDR = (addr, PORT)
print(ADDR)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
msg_length = len("BLOCKCHAIN".encode(FORMAT))
send_type_length = str(msg_length).encode(FORMAT)
send_type_length += b' ' * (HEADER - len(send_type_length))
print(send_type_length.decode(FORMAT) + "ok")
client.send(send_type_length)
client.send("BLOCKCHAIN".encode(FORMAT))
with open("data/blockchain.json") as chain_file:
chain = json.load(chain_file)
chain_se = json.dumps(chain)
print(chain_se)
chain_msg = chain_se.encode(FORMAT)
msg_length = len(chain_msg)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(chain_msg)
print(client.recv(2048).decode(FORMAT))
我有大量的print语句用于调试,基本上长度不错,但是消息被截断了。计算机1将功能req_区块链调用到计算机2,然后一切都是自动的。与1一起工作,从2请求,但不是另一种奇怪的方式。信息被剪切的位置每次都会改变。在发送端,消息已满,在接收端,消息被截断。似乎您在客户端启动了两次连接。一次进入请求链,一次进入发送链。我猜你的“如果”状态不正确,无法将其发回。查看带有-client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)的行,TCP不使用或不理解“消息”。这是一条小溪。如果发送1024个字节,收件人可能会收到10个字节,然后在最后一次
read()
上收到1000个字节,然后收到14个字节。没有消息边界。您需要知道需要多少字节,然后在循环中读取,直到得到所有字节。@MarkSetchell解决了这个问题,addind a loop,thanksAlso seeksocket.makefile
,它用.read()
和.readline()
方法将套接字包装在一个类似文件的对象中,这些方法缓冲套接字并读取请求的字节数(除非关闭)或分别读取换行符。