Python套接字不接收而不发送 [英] Python socket not receiving without sending

查看:47
本文介绍了Python套接字不接收而不发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 python 文档中复制了 echo 服务器示例,它运行良好.但是当我编辑代码时,它不会将数据发送回客户端,socket.recv() 方法在第二次调用时不会返回.

I copied the echo server example from the python documentation and it's working fine. But when I edit the code, so it wont send the data back to the client, the socket.recv() method doesn't return when it's called the second time.

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
conn.sendall(b'ok')
conn.close()

在 python 文档的原始版本中,while 循环略有不同:

In the original version from the python documentation the while loop is slightly different:

while True:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)

客户代码:

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))

推荐答案

TCP 套接字是数据流.一侧的发送呼叫和另一侧的接收呼叫之间没有一对一的相关性.根据您实施的协议,存在更高级别的相关性.在原始代码中,规则是服务器将发送它接收到的内容,直到客户端关闭连接的传入端.然后服务器关闭了套接字.

TCP sockets are streams of data. There is no one-to-one correlation between send calls on one side and receive calls on the other. There is a higher level correlation based on the protocol you implement. In the original code, the rule was that the server would send exactly what it received until the client closed the incoming side of the connection. Then the server closed the socket.

随着你的改变,规则也改变了.现在服务器继续接收和丢弃数据,直到客户端关闭连接的传入端.然后服务器发送ok"并关闭套接字.

With your change, the rules changed. Now the server keeps receiving and discarding data until the client closes the incoming side of the connection. Then the server sends "ok" and closes the socket.

使用第一条规则的客户端挂起,因为它在关闭套接字之前等待数据.如果它想使用这个新的服务器规则,它必须关闭它的套接字的输出端,告诉服务器它完成了,然后它才能得到返回数据.

A client using the first rule hangs because its expecting data before it closes the socket. If it wants to work with this new server rule, it has to close its outgoing side of the socket to tell the server its done, and then it can get the return data.

我已经更新了客户端和服务器以关闭部分连接,并且还让客户端执行多个 recv,以防传入的数据碎片化.不太完整的实现似乎适用于小负载,因为您不太可能获得碎片,但在实际生产代码中会严重损坏.

I've updated the client and server to shutdown parts of the connection and also have the client do multiple recv's in case the incoming data is fragmented. Less complete implementations seem to work for small payloads because you are unlikely to get fragmentation, but break horribly in real production code.

服务器

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()

客户

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:
    buf = s.recv(1024)
    if not buf:
        break
    data += buf
s.close()
print('Received', repr(data))

这篇关于Python套接字不接收而不发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆