为什么我在套接字中收到一个字符串,直到python中的\n换行符转义序列为止?

cur*_*ous 7 python sockets

它应该从一个tcp套接字接收一个2行字符串但实际上我只接收字符串直到新行.

     socket = socket(AF_INET,SOCK_STREAM)
     socket.connect((ip,port))
     data = socket.recv(1024)
     print "%s" % data
Run Code Online (Sandbox Code Playgroud)

如果现在调用接收函数它将在断行后接收字符串的第二部分.这不是我想要的事实.它应该从第一次调用返回整个字符串.当我使用nc连接到服务器时,我通常在连接开始时收到字符串.为什么会发生这种情况?

Som*_*ude 8

因为TCP是一种流媒体协议(如图所示SOCK_STREAM),所以没有固定的消息边界或数据包,您只能通过一次调用就无法确定是否获得了所有内容recv.你只需要recv在循环中调用,添加到缓冲区,并在你认为有足够的时候退出循环.大多数纯文本协议使用换行符来告知已完成读取并使用接收到的数据执行某些操作.其他协议使用其他字符或字节序列.

在您的情况下,如果没有特殊字符表示已达到当前数据的结尾,则您有两个解决方案:

  1. 使用超时:如果一段时间内未收到新数据,请将其打印出来.

  2. 非阻塞套接字:只需在循环中读取,将数据附加到内部缓冲区.当调用recv抛出errno等于的错误时errno.EWOULDBLOCK,则暂时不再读取并打印接收的数据.

备选方案2与包装一起select,可能是最好的方式.

编辑

这是我的意思的一个简单例子.它可能不会像这样工作,需要一些调整,但希望它足以让你继续前进.

# Need to import: package socket, package select, package errno

# Create socket and connect to server

# Make the socket non-blocking (see http://docs.python.org/library/socket.html#socket.socket.setblocking)
socket.setblocking(0)

run_main_loop = True
while run_main_loop:
    # Wait for events...
    read_ready, _, _ = select.select([socket], None, None)

    if socket in read_ready:
        # The socket have data ready to be received
        buffer = ''
        continue_recv = True

        while continue_recv:
            try:
                # Try to receive som data
                buffer += socket.recv(1024)
            except socket.error, e:
                if e.errno != errno.EWOULDBLOCK:
                    # Error! Print it and tell main loop to stop
                    print 'Error: %r' % e
                    run_main_loop = False
                # If e.errno is errno.EWOULDBLOCK, then no more data
                continue_recv = False

    # We now have all data we can in "buffer"
    print '%r' % buffer

socket.close()
Run Code Online (Sandbox Code Playgroud)

  • Python库是否严重不能在更高级别为此提供适用的包装器?(我想这取决于OP真正想做的事情,整体......) (3认同)