在Python中使用键盘快捷键终止客户端连接到服务器

问题描述:

我正在尝试修改在python中实现的服务器和客户端聊天脚本。其中一个要求是当用户输入CTRL-D时客户端退出。我的问题是我如何阅读用户键入(ctrl-D)并在此代码中实现它。我应该关闭像c_socket.close()这样的套接字而没有任何消息返回到我正在退出的服务器吗?在Python中使用键盘快捷键终止客户端连接到服务器

谢谢!

# telnet program example 
import socket, select, string, sys 
import readline 
def prompt() : 
    sys.stdout.write('<You> ') 
    sys.stdout.flush() 

#main function 
if __name__ == "__main__": 

    if(len(sys.argv) < 3) : 
     print 'Usage : python MClient hostname port' 
     sys.exit() 

    host = sys.argv[1] 
    port = int(sys.argv[2]) 

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

    # connect to remote host 
    try : 
     s.connect((host, port)) 
    except : 
     print 'Unable to connect' 
     sys.exit() 

    print 'Connected to remote host. Start sending messages' 
    prompt() 

    while 1: 
     socket_list = [sys.stdin, s] 

     # Get the list sockets which are readable 
     read_sockets, write_sockets, error_sockets = select.select(socket_list , [], []) 

     for sock in read_sockets: 
      #incoming message from remote server 
      if sock == s: 
       data = sock.recv(4096) 
       if not data : 
        print '\nDisconnected from chat server' 
        sys.exit() 
       else : 
        #print data 
        sys.stdout.write(data) 
        prompt() 

      #user entered a message 
      else : 
       msg = sys.stdin.readline() 
       s.send(msg) 
       prompt() 

最后一件事 - 首先是否需要在关闭套接字之前向服务器发送内容取决于您的协议。鉴于所提供的客户端代码的简单性,我猜想关闭套接字应该足够了(无论如何,服务器应该对待未通知的断开连接,因为不应将网络I/O视为持久连接)。

其次,CTRL + d会导致返回消息sys.stdin.readline()返回为空的,所以你可以测试针对的是,如:

msg = sys.stdin.readline() 
if msg: 
    s.send(msg) 
    prompt() 
else: 
    s.close() 
    sys.exit() 

如果你真的需要发送一些东西到服务器(同样,取决于协议),在调用close()之前,您可以使用套接字的shutdown()方法。

但是,请记住,这里给出的代码并不考虑从套接字读取(即接收数据)时按下CTRL + D,因此如果在CTRL + D中获得特别长的数据流不会被注册。您可以通过在检索过程中检查用户输入(并将其写入缓冲区以供稍后发送)来解决此问题,也可以将接收代码放在单独的线程中,并让主线程仅用于用户输入。

然后,您可以随时使用atexit模块干净地退出客户端。

+0

谢谢!像我想要的那样工作。 –