Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python套接字未发送未接收_Python_Sockets - Fatal编程技术网

Python套接字未发送未接收

Python套接字未发送未接收,python,sockets,Python,Sockets,我从python文档中复制了echo服务器示例,它运行良好。但是当我编辑代码时,它不会将数据发送回客户端,socket.recv方法在第二次调用时不会返回 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',

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

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循环略有不同:

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))

接收和发送操作的数量必须匹配,因为它们处于阻塞状态。这是代码的流程图:

Server listen 
Client connect 
Server receive (this waits until a message arrives at the server) [1] 
Client send 'Hello world' (received by [1])
Server receive (because there was data received) [2]
Client receive [3]
由于服务器和客户端现在被阻止,因此任何程序都无法继续


修复方法是删除客户端的接收呼叫,因为您删除了服务器的发送呼叫。

TCP套接字是数据流。一方的发送呼叫与另一方的接收呼叫之间没有一对一的关联。基于您实现的协议,存在更高级别的相关性。在最初的代码中,规则是服务器将准确地发送它接收到的内容,直到客户端关闭连接的传入端。然后服务器关闭了套接字

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

使用第一条规则的客户端挂起,因为它在关闭套接字之前需要数据。如果它想使用这个新的服务器规则,它必须关闭套接字的传出端,告诉服务器它的操作已经完成,然后它才能获得返回数据

我已经更新了客户端和服务器,以关闭部分连接,并让客户端执行多个recv,以防传入的数据被分割。不太完整的实现似乎适用于较小的有效负载,因为您不太可能获得碎片,但在实际的生产代码中会出现可怕的中断

服务器

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))

客户端的源代码在哪里?您只是直接与nc或telnet连接吗?在客户端关闭连接之前,接收不会返回。但是客户端在收到某个信息之前不会关闭连接。我首先要在客户端收到服务器的“确定”后关闭连接。。。在我的情况下我该怎么做?你能解释一下你为什么要第二次打电话给recv吗?另外,为什么客户端关闭套接字而不确保它已收到服务器打算发送的所有内容?如果客户端正在发送更大的数据,并且1024缓冲区不够大,那么,好的,谢谢!是否有一种方法可以在接收到所有数据后将答案发送给客户端?@no0by5:客户端需要告诉服务器它将发送多少数据,以便服务器知道要传递给recv的值。现在,服务器正在尝试接收客户端发送的所有内容,直到客户端关闭连接。如果客户端停止发送并等待回复而不是关闭连接,那么这将无法正常工作。谢谢,这正是我要寻找的!