为啥在从服务器接收到所有数据后客户端套接字连接没有关闭?

Posted

技术标签:

【中文标题】为啥在从服务器接收到所有数据后客户端套接字连接没有关闭?【英文标题】:Why client socket connection is not closed after all data received from server?为什么在从服务器接收到所有数据后客户端套接字连接没有关闭? 【发布时间】:2016-12-02 21:42:49 【问题描述】:

我正在学习python中的socket编程,

服务器代码:

import socket

srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srvsock.bind(('', 23000))
srvsock.listen(5)

while True:
    clisock, (rem_host, rem_port) = srvsock.accept()
    print "conection established with host %s and port %s" % (rem_host, rem_port)
    while True:
        strg = clisock.recv(20)
        if not strg:
            print 'conection closed'
            clisock.close()
            break
        clisock.send(strg)

客户代码:

import socket

clisock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clisock.connect(('', 23000))
clisock.send("Hello World rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr dsadsadsa tttttt\n")
while True:
    data = clisock.recv(20)
    print type(data)
    if not data:
        clisock.close()
        break
    print data

我正在从客户端向服务器发送数据流,同时从服务器接收数据,数据传输成功后,服务器没有关闭客户端连接。我错过了什么吗?

【问题讨论】:

【参考方案1】:

这个问题是因为服务器一直从客户端读取数据,直到它没有读取数据。这只发生在连接的客户端关闭其连接时。在此之前,服务器套接字将阻塞(即暂时挂起操作),直到客户端发送更多数据。

底线:客户端或服务器必须表明它不再打算通过连接发送数据。

您可以通过添加该行来修复客户端

clisock.shutdown(socket.SHUT_WR)

在客户端的for 循环之前。这表示将不再发送数据。

【讨论】:

请注意:协议设计中最重要的部分之一是确保协议单元(数据包、数据帧等)可以相互分离。您正在尝试实现一个无法检测“消息结束”并且没有发送“传输结束”的协议。【参考方案2】:

服务器代码:

while True:
    clisock, (rem_host, rem_port) = srvsock.accept()
    print "conection established with host %s and port %s" % (rem_host, rem_port)
    while True:
        strg = clisock.recv(20)
        print '[message from client:] %s'%strg
        clisock.send(strg)
        print 'about to close with client'
        clisock.close()
        print 'connection closed with client'
        break

客户端代码:

clisock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clisock.connect(('', 23000))
clisock.send("Hello World rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr dsadsadsa tttttt\n")
while True:
    data = clisock.recv(20)
    print '[Message from server :]%s'%data
    print 'about to close server connection'
    clisock.close()
    print 'server connection closed'
    break

这将在您的情况下解决,holdenweb 有一个正确的答案,为什么您的代码在上述代码中的行为不符合预期连接到该客户端 单个客户端 -- 单个连接 ---- 单个消息

【讨论】:

以上是关于为啥在从服务器接收到所有数据后客户端套接字连接没有关闭?的主要内容,如果未能解决你的问题,请参考以下文章

为啥tcp服务器可以获取客户端的ip?

Java 套接字服务器只显示连接关闭后收到的消息

自己用C语言构造数据包,实现TCP三次握手过程,为啥中间会产生一个RST信号?

颤振流套接字

为啥我的 TCP 服务器套接字在一个客户端断开连接后关闭?

Android - 客户端关闭连接发送图像,然后接收回字符串