【问题标题】:Sending to a disconnected socket succeeds the first time [duplicate]发送到断开连接的套接字第一次成功[重复]
【发布时间】:2021-10-30 02:10:48
【问题描述】:

在 TCP 客户端-服务器通信中,当客户端在服务器断开连接后尝试发送到服务器时,第一次尝试send()(据称)成功,所有后续尝试都以[Errno 32] Broken pipe 失败。最小的例子:

import socket
import sys
import time

SERVER_ADDR = ("127.0.0.1", 65432)


def server(s):
    s.bind(SERVER_ADDR)
    s.listen()
    print(f"Server listening for clients at {SERVER_ADDR}")
    conn, addr = s.accept()
    with conn:
        print("Connected by", addr)


def client(s, msg):
    s.connect(SERVER_ADDR)
    time.sleep(1)
    for i in range(1, 10):
        print(f"Sending {msg} - attempt {i}")
        try:
            nbytes = s.send(msg)
            print(f"{nbytes} bytes sent out of {len(msg)} in total")
        except OSError as ex:
            print(ex)


if __name__ == "__main__":
    msg = " ".join(sys.argv[1:]).encode("utf8")
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        if msg:
            client(s, msg)
        else:
            server(s)
  1. 启动服务器:
python run.py 
Server listening for clients at ('127.0.0.1', 65432)
  1. 启动客户端:
python run.py hello world
Sending b'hello world' - attempt 1
11 bytes sent out of 11 in total
Sending b'hello world' - attempt 2
[Errno 32] Broken pipe
Sending b'hello world' - attempt 3
[Errno 32] Broken pipe
Sending b'hello world' - attempt 4
[Errno 32] Broken pipe
Sending b'hello world' - attempt 5
[Errno 32] Broken pipe
Sending b'hello world' - attempt 6
[Errno 32] Broken pipe
Sending b'hello world' - attempt 7
[Errno 32] Broken pipe
Sending b'hello world' - attempt 8
[Errno 32] Broken pipe
Sending b'hello world' - attempt 9
[Errno 32] Broken pipe
  • 为什么会这样?
  • 我如何才能 (a) 使第一次尝试也失败,或者 (b) 在发送之前检测连接是否存在?

【问题讨论】:

    标签: python sockets tcp


    【解决方案1】:

    为什么会这样?

    this answerWriting to a closed, local TCP socket not failing有详细说明。

    我怎样才能 (a) 使第一次尝试也失败,或者 (b) 在发送之前检测连接是否存在?

    您可以通过在s.accept 行之后使用SO_LINGER 套接字选项强制服务器立即关闭套接字来使第一次尝试失败:

    conn.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
    

    【讨论】:

      猜你喜欢
      • 2022-09-28
      • 2019-03-05
      • 2016-08-09
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多