Python socket Recv 不能正常工作有人可以解释一下

use*_*967 5 python sockets

我正在尝试为我的命令行服务器创建一个 gui 客户端。但是,我遇到了一些我似乎无法解决的烦人问题。

我不是 100% 确定实际问题是什么,因为有时代码会起作用,有时则不会。我认为主要问题是最初我尝试了

while 1:
    self.data = s.recv(1024)
    if not self.data():
          break
    else:
          print self.data()
Run Code Online (Sandbox Code Playgroud)

然后我用这个发送给它

  for f in files:
      s.send(f)
Run Code Online (Sandbox Code Playgroud)

每个 f 都是一个文件名字符串。我希望它会在 recv 端出现,因为每个 recv 调用都会收到一个文件名,但在一次 recv 调用中,我得到了一大块文件名,我认为 1024 个字符值得

这使得无法检查数据的结尾,因此循环从未退出。

这是我现在的代码

def get_data(self,size = 1024):

    self.alldata = ""
    while 1:

        while gtk.events_pending():
             gtk.main_iteration()

        self.recvdata = self.s.recv(size)
        self.alldata += self.recvdata
        if self.alldata.find("\r\n\r\nEOF"):
           print "recieved end message"
           self.rdata = self.alldata[:self.alldata.find("\r\n\r\nEOF")]
           break



    print "All data Recieved: " + str(len(self.rdata)) + "Bytes"
    print "All data :\n" + self.rdata + "\n-------------------------------------------------"  

    self.infiles = self.rdata.split("-EOS-")
    for nf in self.infiles:
        if len(nf) > 2:
            self.add_message(self.incomingIcon,nf)
Run Code Online (Sandbox Code Playgroud)

此刻我试图让客户端从服务器正确读取。我想要发生的是,当输入命令列表并将其发送到客户端时,服务器会发回数据并将每个文件附加到列表存储中

有时这可以正常工作,有时仅返回 1200 个文件中的一个,如果它执行正常,如果我尝试键入另一个命令并发送它,整个 gtk 窗口就会消失并且程序变得无响应。

抱歉,我无法更好地解释这个问题,我尝试了很多不同的解决方案,所有这些解决方案都给出了不同的错误。

如果有人可以解释 recv 命令以及为什么它可能会给出错误,这就是我向客户端发送数据的方式

if(commands[0] == 'list'):
    whatpacketshouldlooklike=""
    print "[Request] List files ", address
    fil = list_files(path)
    for f in fil:
         sdata =  f  
         whatpacketshouldlooklike += sdata + "-EOS-"
         newSock.send(sdata +"-EOS-")
         #print "sent: " + sdata
         newSock.send("\r\n\r\nEOF")
    whatpacketshouldlooklike += "\r\n\r\nEOF"
    print "---------------------------------"
    print whatpacketshouldlooklike
    print "---------------------------------"
Run Code Online (Sandbox Code Playgroud)

sto*_*tal 3

您在第一部分中遇到的问题是套接字是基于流的而不是基于消息的。您需要提出一个消息抽象来分层在流之上。这样,管道的另一端知道发生了什么(作为一个命令的一部分期望有多少数据)并且不会猜测应该发生什么。