【问题标题】:Why is socket.recv() sometimes blocking and sometimes not? [duplicate]为什么 socket.recv() 有时会阻塞,有时不会? [复制]
【发布时间】:2019-12-11 15:40:49
【问题描述】:

我正在尝试制作一个客户端-服务器应用程序,其中:

  • 客户端向服务器发送消息(函数名)
  • 服务器接收到消息,调用相应的函数并将结果返回给客户端。

只有当来自客户端的消息是 1 时,我才能做到这一点;如果我想调用两个或更多函数,从而发送两条或更多消息,我会遇到一些问题,因为我需要在服务器内部添加一个循环。

特别是,我不清楚的是套接字函数recv()。通常,为了接收数据,我会写这样的东西(没有 setblocking()),我从来没有遇到过任何问题:

while True:
    data = sock.recv(BUFFER)
    results += data.decode()
if not data:
    break

但是如果我向服务器添加一个while True:(为了等待其他函数),那么客户端永远不会从 sock.rev() 中退出。为什么?根据 sock.setblocking() 的设置方式,我希望该函数始终处于阻塞状态或始终处于非阻塞状态。

我已经尝试使用 settimeout() 并且它有效,但是性能非常重要,所以我想避免所有可能的延迟。 无论如何,主要问题是为什么 recv() 行为不同;那么如果您对解决我的任务有任何建议,我们将不胜感激。

这是对真实应用程序的简单模拟。

客户:

import socket

BUFFER = 1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address= ('localhost', 14000)

sock.connect(bridge_address)

msg1 = "function 1".encode()
msg2 = "function 2".encode()

results1 = " "
results2 = " "

sock.sendall(msg1)

while True:
    data = sock.recv(BUFFER)
    results1 += data.decode()
    if not data:
        print('no more data')
        break        

sock.sendall(msg2)

while True:
    data = sock.recv(BUFFER)
    results2 += data.decode()
    if not data:
        print('no more data')
        break    

sock.close()

print('Results 1: ',results1)
print('Results 2: ',results2)

服务器:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 14000)
sock.bind(server_address)

sock.listen(1)

msg = ""
for i in range(4096):
    msg += str(i) + " "

while True:
    print('waiting for a connection')
    client, client_address = sock.accept()

    try:
        while True:
            data = client.recv(128)
            if not data:
                print('no more data from')
                break            
            client.sendall(msg.encode())

    finally:
        print('connection closed.\n')
        client.close()

【问题讨论】:

    标签: python sockets server client


    【解决方案1】:

    您明确地强制服务器端套接字接收来自客户端的消息,即使客户端没有发送任何内容。

    data = client.recv(128)
    if not data:
        print('no more data from')
        break
    

    if 上面代码 sn-p 中的 case 只会在客户端套接字关闭时执行。

    解决此问题的一种方法是首先发送消息的大小,然后针对指定的字节数相应地调用recv

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多