如何用Python制作简单的命令行聊天?
我在学习网络编程,想用Python写一个简单的命令行聊天程序。
我想知道怎么才能在接收消息的同时,也能随时输入消息发送出去。
如你所见,这个客户端一次只能做一件事:
from socket import *
HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while 1:
data = raw_input('> ')
if not data: break
tcpCliSock.send(data)
data = tcpCliSock.recv(BUFSIZE)
if not data: break
print data
tcpCliSock.close()
所以如果其他客户端发来消息,这个客户端只能在发送完自己的消息后才能接收到。你应该能理解我的意思。我在网上查了很多资料,发现了很多有趣的东西,比如异步输入输出、线程、非阻塞同步、并发编程等等。我还安装了twisted这个包。总之,我在学习这些东西,但还没找到我想要的解决方案。(当然,我会继续努力,直到找到答案。)
所以,我的问题是怎么做到这一点呢?=)
6 个回答
聊天程序同时在做两件事情。
监听本地用户的键盘输入,并通过某种方式把这些信息发送给远程用户(比如通过一个网络连接)。
监听远程连接,显示他们在本地控制台上输入的内容。
你可以用几种方法来实现这个功能。
一个程序打开网络连接和键盘,然后使用select模块来检查哪个输入准备好了。
一个程序创建两个线程。一个线程读取远程连接的数据并打印出来,另一个线程读取键盘输入并发送到远程连接。
一个程序创建两个子进程。一个子进程读取远程连接的数据并打印,另一个子进程读取键盘输入并发送到远程连接。
如果你想从头开始编写代码,使用 select
是个不错的选择(你可以在谷歌图书搜索中找到《Python in a Nutshell》这本书的大部分章节,里面有讲到这些内容);如果你想用更高级的方式来处理,asyncore
也可以用,但 Twisted 更加丰富和强大。
你的问题表达得不是很清楚。不过,其实你的程序并不需要使用异步方式就能实现你想要的功能。
这是一个可以正常工作的聊天脚本,跟你最初想要的差不多,只做了很少的修改。它使用了1个线程来接收消息,1个线程来发送消息,两个线程都使用了阻塞式的套接字。这种方式比使用异步方法简单得多。
from socket import *
from threading import Thread
import sys
HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
def recv():
while True:
data = tcpCliSock.recv(BUFSIZE)
if not data: sys.exit(0)
print data
Thread(target=recv).start()
while True:
data = raw_input('> ')
if not data: break
tcpCliSock.send(data)
tcpCliSock.close()