Python 连续接收与接收;通过套接字发送

Python 连续接收与接收;通过套接字发送,python,sockets,Python,Sockets,我正在做一项工作,我需要连接到一台服务器(没有透露服务器的详细信息),捕获回复,修改它并将其发送回以进行验证 我已经创建了下面的代码,它满足了我的需要,但问题是在第一次正确的回复之后,服务器会发送另一个 代码: #-*-编码:utf-8-*- 导入套接字 从decryptmsg导入decryptmsg 从cleanmsg导入cleanmsg #联系 ip=“” 端口=4000 sock=socket.socket(socket.AF\u INET,socket.sock\u流) sock.con

我正在做一项工作,我需要连接到一台服务器(没有透露服务器的详细信息),捕获回复,修改它并将其发送回以进行验证

我已经创建了下面的代码,它满足了我的需要,但问题是在第一次正确的回复之后,服务器会发送另一个

代码:

#-*-编码:utf-8-*-
导入套接字
从decryptmsg导入decryptmsg
从cleanmsg导入cleanmsg
#联系
ip=“”
端口=4000
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
sock.connect((ip,端口))
def recvall(短袜):
缓冲区=8192
数据=b''
尽管如此:
部分=sock.recv(缓冲区)
数据+=零件
如果len(部分)<缓冲器:
打破
返回数据
尽管如此:
打印“[+]开始通信”
数据=recvall(sock)
打印数据
数据=cleanmsg(数据)
如果是数据!=无:
valmis=decryptmsg(str(数据))
如果valmis==无:
打印“[-]无结果”
打破
其他:
打印“[+]发送消息…”
短袜发送(valmis)
持续
当我遇到第二个问题时,我用这段代码捕获了输入,并按预期进行了处理,但当我尝试发回第二个回复时,我得到了错误:

Traceback (most recent call last):
File "challenge.py", line 28, in <module>
     sock.send(valmis)
socket.error: [Errno 32] Broken pipe
回溯(最近一次呼叫最后一次):
文件“challenge.py”,第28行,在
短袜发送(valmis)
socket.error:[Errno 32]管道破裂
如果我不关闭或关闭套接字,则不会向服务器发送回复

在没有socket.shutdown的情况下,如何告诉我的客户端发送消息并等待回复?或者,如果我需要为每个循环打开新的套接字,那么应该如何构造循环?来自服务器的回复每次都会发生变化,所以如果我完全打开新连接并请求数据,我会得到新的回复,整个过程将从头开始

更新:
问题似乎是当尝试从服务器接收第二条回复时,客户端只接收第一行消息。

您如何知道它没有发送任何内容?我对您的代码做了一些修改(else:子句中有一些奇怪的地方,我稍后会回来讨论)

基本上,这是一个精简版的代码-没有解密或外部功能。它只是发回它从服务器接收到的任何信息

然后我用ncat运行了一个“服务器”:

ncat -l 4000
启动你的程序,开始输入行(1,2,3,4等),这发生在“服务器”。客户立即回复我的信息:

test@xyzzy:/tmp$ ncat -l 4000
1
1
2
2
3
3
这在客户端发生:

test@xyzzy:/tmp$ python so.py 
1

[+] sending message... 
2

[+] sending message... 
3

[+] sending message... 
在我看来,这段代码运行良好。如果服务器没有收到您的回复,则可能是服务器端有问题。例如,它可能期望在响应中使用终止符字符。您的
cleanmsg
是否过多地清除了消息,例如删除了尾随的换行符,而服务器希望收到一条

当您在那里执行另一个
sock.recv()
时,您原来的else子句中有一个问题。这意味着在收到回复后,您将在那里阻塞以等待来自服务器的下一条消息,当您确实收到回复时,您将继续循环并再次点击
sock.recv()
。第二条消息已在else子句中使用

如果您的服务器以某种方式确认您的解密,这可能是故意的。如果您的协议是这样的:

server -> client  (request)
client -> server  (decrypted message)
server -> client  (some kind of acknowledgement - unclear from your code)

server -> client  (request 2)
etc. 
那么你可能在Jason的评论中找到了问题所在。TCP套接字对于消息的概念是完全不可知的。他们只是传输数据。当代码点击sock.recv()时,可能会发生以下五种情况之一:

  • 套接字和调用块中没有任何内容
  • 有一个完整的“消息”,只有在插座和你收到它
  • 有一个部分消息,您将收到它。要么是因为消息超过8192字节,要么是因为您的代码决定在服务器只传输了部分消息数据时读取
  • 有两条或更多完整的“消息”正在等待,您将收到它们
  • 第四条,但最后一条信息是不完整的
  • 在使用TCP套接字操作时,必须始终满足场景2-5的要求。你必须解析数据,确保所有的东西都在那里,如果没有,等待更多。如果有比您预期的更多的内容,请相应地进行处理。如果它们是完整的消息,请处理它们。如果最后一条消息是部分消息,请处理所有其他消息并等待更多消息

    如果消息似乎在使用TCP套接字的自制通信协议中“消失”,99%的问题是由于假设套接字知道或关心“消息”的结构而导致的。一个非常常见的错误是将套接字读空,而忽略第一条消息之后收到的所有内容

    希望这是有帮助的。从套接字通信的角度来看,没有附加recv的代码似乎工作得很好-无需关闭套接字。这可能是服务器端问题、协议问题或消息解析问题


    因此,您的套接字始终只有一个
    recv
    调用。即使您希望得到某种形式的确认而不是新消息,也只有一个地方可以处理套接字数据。然后在那里做一些条件测试来检测你收到了什么样的消息,然后决定如何处理它

    你怎么知道它没有发送任何东西?我对您的代码做了一些修改(else:子句中有一些奇怪的地方,我稍后会回来讨论)

    基本上,这是一个精简版的代码-没有解密或外部功能。它只是发回它从服务器接收到的任何信息

    然后我用ncat运行了一个“服务器”:

    ncat -l 4000
    
    启动你的程序,开始输入行(1,2,3,4等),这发生在“服务器”。客户立即回复我的信息:

    test@xyzzy:/tmp$ ncat -l 4000
    1
    1
    2
    2
    3
    3
    
    这在客户端发生:

    test@xyzzy:/tmp$ python so.py 
    1
    
    [+] sending message... 
    2
    
    [+] sending message... 
    3
    
    [+] sending message... 
    
    在我看来,这段代码运行良好。如果服务器未接收到您的re