【发布时间】:2018-03-21 13:40:31
【问题描述】:
我正在处理我需要连接到服务器的任务(没有透露服务器的详细信息),捕获回复,修改它并将其发回以进行验证。
我创建了以下代码来满足我的需要,但问题是在第一次正确回复后,服务器发送另一个。
代码:
# -*- encoding: utf-8 -*-
import socket
from decryptmsg import decryptmsg
from cleanmsg import cleanmsg
#connection
ip="<IP>"
port=4000
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip,port))
def recvall(sock):
BUFFER = 8192
data = b''
while True:
part = sock.recv(BUFFER)
data += part
if len(part) < BUFFER:
break
return data
while True:
print "[+] start communication"
data = recvall(sock)
print data
data = cleanmsg(data)
if data != None:
valmis = decryptmsg(str(data))
if valmis == None:
print "[-] no results"
break
else:
print "[+] sending message... "
sock.send(valmis)
continue
当我遇到第二个问题时,我使用此代码很好地捕获了输入并按预期进行处理,但是当我尝试发送第二个回复时,我收到错误:
Traceback (most recent call last):
File "challenge.py", line 28, in <module>
sock.send(valmis)
socket.error: [Errno 32] Broken pipe
如果我不关闭或关闭套接字,则不会向服务器发送任何回复。
如何告诉我的客户发送消息并等待没有 socket.shutdown 的回复?或者如果我需要为每个循环打开新的套接字,应该如何构造循环?服务器的回复每次都会改变,所以如果我完全打开新连接并请求数据,我会得到新的回复,并且该过程会重新开始。
更新: 问题似乎是在尝试从服务器接收第二个回复时,客户端只接收到第一行消息。
【问题讨论】:
-
我也用 sendall(data, MSG_DONTWAIT) 进行了测试,结果相同。
-
你的方法从根本上被打破了;绝对没有理由相信在 TCP 流上对
.recv()的单个调用将获得完整的消息(接收的块与另一端发送的块之间没有关联)。任何允许通过单个连接发送多条消息的协议都必须有某种方式来界定它们;通常是不能出现在消息本身中的特定字符或字符串,或者是在每条消息之前传输的长度值。 -
感谢杰森的评论。我会考虑添加某种缓冲区,但我通过这个 recv 获得了正确的数据 - 在这里发送回复是我需要帮助的。
-
无论服务器的编码方式如何,我都会删除第二个
data = sock.recv(8192),因为它发生在while循环的顶部,这意味着数据为无。我的快速测试客户端也不需要shutdown。