Python 如何接收数据并在if()语句中使用它?

Python 如何接收数据并在if()语句中使用它?,python,Python,我已尝试通过python 2.7上的以下代码从我的连接接收数据: server = socket(AF_INET, SOCK_STREAM) server.bind(('0.0.0.0', 21)) server.listen(1) client , addr = server.accept() data = client.recv(2048) 当我必须打印数据或将数据发送到另一个连接时,它正在工作,但我想添加这些行: if(data == "/disc

我已尝试通过python 2.7上的以下代码从我的连接接收数据:

    server = socket(AF_INET, SOCK_STREAM)
    server.bind(('0.0.0.0', 21))
    server.listen(1)
    client , addr = server.accept()
    data = client.recv(2048)
当我必须打印数据或将数据发送到另一个连接时,它正在工作,但我想添加这些行:

if(data == "/disconnect") :
     <disconnect blha blha... you know >
else :
     <print the data and send it back blha blha... >
if(数据==”/disconnect”):
其他:
(我在没有if语句的情况下进行了检查,“断开blha blha…”效果很好)

它只是传递代码,所以当我的客户端请求断开连接时,请求将作为“原始”消息发送到服务器。。(服务器不要踢他)


我该怎么办?谢谢

您有两个问题,需要同时解决这两个问题


首先。当你做一个
recv
时,你不会从另一端得到一条
send
发送的消息,你会得到缓冲区中的任何东西,可能是两条消息,或者半条消息,或者其他任何东西。在许多平台上,当您只是在一台负载不重的计算机上测试本地主机连接时,它将在99%以上的时间内完成您希望的操作,但这只会使问题难以调试,无法解决。一旦你试图通过互联网访问相同的代码,它就会开始在大部分时间失败,而不是很少失败

幸运的是,客户端似乎以文本形式发送消息,没有任何内嵌的换行符,每条消息之间有一个
\r\n
Windows风格的行尾。这是一个非常好的协议;您只需要编写代码来处理接收端的协议

第二个问题是,即使您恰好收到一条消息
send
,该消息也包括
\r\n
行尾。而
'/disconnect\r\n'=='/disconnect'
当然是假的。因此,作为协议处理程序的一部分,您需要去掉换行符


实际上,您可以通过使用该方法为您提供一个可以迭代的文件对象,或
readline
on等来解决这两个问题,就像您从磁盘
打开的文件一样,您可能已经知道如何处理该文件

但是学习如何做这件事是值得的,所以我将向您展示如何手动操作。关键是要保留一个缓冲区,将每个
recv
添加到该缓冲区中,然后将其拆分为行,将剩余部分放回缓冲区,并将每行作为消息处理。有更优雅/简洁的方式来写这篇文章,但让我们保持简单:

buf = ''
while True:
    data = client.recv(2048)
    buf += data
    lines = buf.split('\r\n')
    buf = lines.pop()
    for line in lines:
        # line is now a single message, with the newline stripped
        if line == "/disconnect":
            # do disconnect stuff
        else:
            # do normal message stuff

这就是你所需要的一切,让基本的工作。但在真正的服务器中,您还需要一些代码来处理另外两种情况,因为客户端并不总是完全关闭。例如,如果一个客户端在发送
/disconnect
消息之前就断开了与internet的连接,那么您不希望一直保持旋转和不读取任何内容,而是希望将其视为断开连接

  • 如果不是数据:
    表示客户端已完全(在TCP级别)关闭。因此,您需要断开并中断接收循环。
    • 根据您的设计,只关闭发送端并等待服务器的最终答复可能是合法的,因此您需要确保已完成所有的发送。(这在许多internet协议中很常见。)
    • 在关闭前不发送最后一条新线可能是合法的;如果要支持此操作,应选中
      if buf:
      ,如果是,则将
      buf
      视为最后一个命令。(这在许多协议中并不常见,但在客户端中是一个常见的错误,因此,例如,许多web服务器将处理它。)
  • try:
    /
    异常除外,因为e:
    将捕获所有类型的错误。这些错误意味着套接字不再可用(或者代码中存在严重错误),因此您希望通过丢弃连接并中断接收循环来处理此问题,而不首先发送任何最终响应或读取任何最终消息。
    • 以某种方式记录
      e
      (可能只是
      print'Error from',addr,repr(e)
      )几乎总是值得的,因此如果您遇到意外异常,您需要调试一些东西

当您调用
client.recv(2048)
时,您可能会从客户端获得
send
的前两个字节,或者整个内容,或者一个
send
的最后一部分,另外两个
send
的前两个字节,以及第四个
的第一部分。因此,不太可能等于
/断开连接
。如果你想用TCP处理消息而不是字节,你必须提出一个消息帧协议。最简单的一种是,每条消息都是以
b'\n'
结尾的一组字节,或者是以UTF-8编码的
'\n'
结尾的一组UTF-8编码字符。如果您的消息可以包含嵌入的换行符,那么这是不起作用的,但是如果它们不能,那就非常容易了,特别是因为
socket
对象上的
makefile
方法为您完成了整个协议的实现。如果您不确定这是否是问题所在,请尝试添加
print(repr(data))
下载到服务器,查看打印出的内容。如果您得到了
'/disco'
'/me要离开\n/disconnect'
或类似的东西,这是您的问题,这是一个重复(以及我们可以查找和添加的各种其他重复)。如果你得到了一些不同的东西,那么你可能还有另外一个问题,但是我们不能调试它,除非你告诉我们你得到了什么。(查看示例客户端和示例用户输入(如果相关)也会有所帮助。)编写端口:21主机名:DESKTOP-7G40JN7服务器侦听:(my_ip):21(phone_ip):已连接!(电话ip):'dmdk\r\n'(电话ip):'hey\r\n'#输出的“hey”在流中的任何位置都不包含
/discconnect
。那么,为什么您希望
data==“/disconnect”
为真?