套接字关闭处理程序和代理

时间:2012-03-22 02:44:18

标签: python sockets

我在python中做一些基本的套接字编程。但是我很难弄清楚我的回忆者如何注意到回声已关闭它的连接,没有持续的ping / pong或超时。

echoclient.py

#echoclient
import sys
import socket
import os
import datetime

def log(s):
    return datetime.datetime.now().strftime('%H:%M:%S') + ' - ' + s

s = socket.socket(
    socket.AF_INET, socket.SOCK_STREAM)

s.connect(('127.0.0.1', 9000))

while 1:
    try:
        foo = raw_input('what do you want to send?: ')
        if len(foo) > 0:
            s.send(foo)
    except KeyboardInterrupt:
        print 'shutting down connection'
        s.close()
        break
    data = s.recv(1024)
    if data:
        print log('Recieved'), repr(data)

echoserver.py

#echoserver
import sys
import socket
import os
import datetime

def log(s):
    return datetime.datetime.now().strftime('%H:%M:%S') + ' - ' + s

port = 9000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', port))
s.listen(5)

while 1:
    conn, addr = s.accept()
    conn.settimeout(10)
    print 'Connected by', addr
    while 1:
        try:
            data = conn.recv(1024)
            if data:
                print log(repr(data))
                conn.send(data)
        except KeyboardInterrupt:
            print 'Closing connection ', addr
            conn.close()
            sys.exit(1)
        except:
            print 'Exception caught! closing connection ', addr
            conn.close()
            break           

现在服务器知道客户端已经死亡的唯一方法是conn.settimeout(10)

  1. 当客户端断开连接时,如果它们之间没有constat ping / pong消息或settimeout,我怎样才能获得服务器的异常。

  2. 我的下一步是在echoclient和echoserver之间创建一个echoproxy,我需要使用线程/多处理来实现这一目标吗?任何提示或指示?

  3. 欢迎任何其他有关不良/良好做法的评论

  4. 谢谢!

3 个答案:

答案 0 :(得分:1)

据我所知,套接字库在clients disconnect时已收到消息。

  

严格地说,在关闭套接字之前,你应该在套接字上使用shutdown。关闭是对另一端套接字的建议。根据您传递的论点,它可能意味着“我不会再发送了,但我仍然会听”,或者“我不是在听,也不是很好!”。然而,大多数套接字库都习惯于程序员忽略使用这种礼仪,通常关闭与shutdown()相同;关()。因此在大多数情况下,不需要显式关闭。

     

服务器可以通过接收0字节来检测“EOF”。它可以假设它有完整的请求。服务器发送回复。如果发送成功完成,那么客户端仍在接收。

当另一端突然断开连接(如网络故障或崩溃)时超时发挥作用。

在上面的服务器代码中,您应该能够使用以下方法立即检测客户端断开连接:

if data:
   # process data
else:
   # client disconnected

答案 1 :(得分:0)

Python套接字库是一个低级实现,因此使用起来可能很棘手。我建议使用更高级别的东西,比如Twisted。您可以使用connectLost方法在Twisted中完成您正在寻找的内容。

from twisted.internet.protocol import Protocol

class Echo(Protocol):
    def connectLost(self, reason):
        pass

有关详细信息,请参阅http://twistedmatrix.com/documents/current/core/howto/servers.html

(扭曲也可能使代理更容易实现。)

答案 2 :(得分:0)

在致电socket.shutdown()之前使用socket.close()。阅读socket.close() here

的注释