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

2024-04-25 05:26:22 发布

您现在位置: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 == "/disconnect") :
     <disconnect blha blha... you know >
else :
     <print the data and send it back blha blha... >

(我在没有if语句和“disconnect blha blha..”的情况下进行了检查)(效果很好)

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

我该怎么办?谢谢!你知道吗


Tags: 代码clientdatastreamifserverbindsocket
1条回答
网友
1楼 · 发布于 2024-04-25 05:26:22

你有两个问题,你需要解决它们。你知道吗


首先,a TCP socket is just a stream of bytes。当你做一个recv时,你不会从另一方得到send发送的一条消息,你会得到缓冲区中的任何东西,可能是两条消息,或者半条消息,或者其他任何东西。在许多平台上,当您只是在负载不重的计算机上使用localhost连接进行测试时,它将完成您希望的>;99%的时间,但这只会使问题难以调试,无法解决。一旦你尝试在互联网上访问相同的代码,它将开始失败的大部分时间,而不是很少。你知道吗

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

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


碰巧,您可以通过使用^{}方法来解决这两个问题,从而为您提供一个可以迭代的文件对象,或readline等,就像您从磁盘open处理文件一样,您可能已经知道如何处理它。你知道吗

但是如何做这些东西是值得学习的,所以我将向您演示如何手动执行。关键是要保留一个缓冲区,将每个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的连接,那么您不希望一直旋转,什么也不读,而是希望将其视为断开连接。你知道吗

  • if not data:意味着客户端已经完全关闭(在TCP级别)。因此,您需要断开并中断接收循环。
    • 根据您的设计,只关闭发送端并等待服务器的最终答复可能是合法的,因此您需要确保您已经完成了所有的发送。(这在许多互联网协议中很常见。)
    • 在关机之前不发送最后一个换行符可能是合法的;如果您想支持这一点,您应该选中if buf:,如果是,请将buf视为最后一个命令。(这在许多协议中并不常见,但在客户机中是一个常见的错误,因此,例如,许多web服务器将处理它。)
  • try:/except Exception as e:将捕获各种错误。这些错误意味着套接字不再可用(或者代码中当然存在严重错误),因此您希望通过丢弃连接并中断接收循环来处理此问题,而不首先发送任何最终响应或读取任何最终消息。
    • 以某种方式记录e几乎总是值得的(也许只是print 'Error from', addr, repr(e)),因此如果您遇到意外的异常,您需要调试一些东西。你知道吗

相关问题 更多 >