如何使用多线程在python中创建多客户端服务器?
这是我使用的代码。但我没有得到我想要的实际结果。当我执行代码时,ChatServer文件工作正常,但ChatClient只提供一行用法:python telnet.py主机名端口。请帮助我。我是python新手 服务器代码:如何使用多线程在python中创建多客户端服务器?,python,multithreading,python-2.7,Python,Multithreading,Python 2.7,这是我使用的代码。但我没有得到我想要的实际结果。当我执行代码时,ChatServer文件工作正常,但ChatClient只提供一行用法:python telnet.py主机名端口。请帮助我。我是python新手 服务器代码: #!/usr/bin/env python #!/usr/bin/env python """ A basic, multiclient 'chat server' using Python's select module with interrupt handling.
#!/usr/bin/env python
#!/usr/bin/env python
"""
A basic, multiclient 'chat server' using Python's select module
with interrupt handling.
Entering any line of input at the terminal will exit the server.
"""
import select
import socket
import sys
import signal
from communication import send, receive
BUFSIZ = 1024
class ChatServer(object):
""" Simple chat server using select """
def __init__(self, port=3490, backlog=5):
self.clients = 0
# Client map
self.clientmap = {}
# Output socket list
self.outputs = []
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind(('',port))
print 'Listening to port',port,'...'
self.server.listen(backlog)
# Trap keyboard interrupts
signal.signal(signal.SIGINT, self.sighandler)
def sighandler(self, signum, frame):
# Close the server
print 'Shutting down server...'
# Close existing client sockets
for o in self.outputs:
o.close()
self.server.close()
def getname(self, client):
# Return the printable name of the
# client, given its socket...
info = self.clientmap[client]
host, name = info[0][0], info[1]
return '@'.join((name, host))
def serve(self):
inputs = [self.server,sys.stdin]
self.outputs = []
running = 1
while running:
try:
inputready,outputready,exceptready = select.select(inputs, self.outputs, [])
except select.error, e:
break
except socket.error, e:
break
for s in inputready:
if s == self.server:
# handle the server socket
client, address = self.server.accept()
print 'chatserver: got connection %d from %s' % (client.fileno(), address)
# Read the login name
cname = receive(client).split('NAME: ')[1]
# Compute client name and send back
self.clients += 1
send(client, 'CLIENT: ' + str(address[0]))
inputs.append(client)
self.clientmap[client] = (address, cname)
# Send joining information to other clients
msg = '\n(Connected: New client (%d) from %s)' % (self.clients, self.getname(client))
for o in self.outputs:
# o.send(msg)
send(o, msg)
self.outputs.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
try:
# data = s.recv(BUFSIZ)
data = receive(s)
if data:
# Send as new client's message...
msg = '\n#[' + self.getname(s) + ']>> ' + data
# Send data to all except ourselves
for o in self.outputs:
if o != s:
# o.send(msg)
send(o, msg)
else:
print 'chatserver: %d hung up' % s.fileno()
self.clients -= 1
s.close()
inputs.remove(s)
self.outputs.remove(s)
# Send client leaving information to others
msg = '\n(Hung up: Client from %s)' % self.getname(s)
for o in self.outputs:
# o.send(msg)
send(o, msg)
except socket.error, e:
# Remove
inputs.remove(s)
self.outputs.remove(s)
self.server.close()
if __name__ == "__main__":
ChatServer().serve()
聊天客户端:
#! /usr/bin/env python
"""
Simple chat client for the chat server. Defines
a simple protocol to be used with chatserver.
"""
import socket
import sys
import select
from communication import send, receive
BUFSIZ = 1024
class ChatClient(object):
""" A simple command line chat client using select """
def __init__(self, name, host='127.0.0.1', port=3490):
self.name = name
# Quit flag
self.flag = False
self.port = int(port)
self.host = host
# Initial prompt
self.prompt='[' + '@'.join((name, socket.gethostname().split('.')[0])) + ']> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, self.port))
print 'Connected to chat server@%d' % self.port
# Send my name...
send(self.sock,'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '@'.join((self.name, addr)) + ']> '
except socket.error, e:
print 'Could not connect to chat server @%d' % self.port
sys.exit(1)
def cmdloop(self):
while not self.flag:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin & socket
inputready, outputready,exceptrdy = select.select([0, self.sock], [],[])
for i in inputready:
if i == 0:
data = sys.stdin.readline().strip()
if data: send(self.sock, data)
elif i == self.sock:
data = receive(self.sock)
if not data:
print 'Shutting down.'
self.flag = True
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print 'Interrupted.'
self.sock.close()
break
if __name__ == "__main__":
import sys
if len(sys.argv)<3:
sys.exit('Usage: %s chatid host portno' % sys.argv[0])
client = ChatClient(sys.argv[1],sys.argv[2], int(sys.argv[3]))
client.cmdloop()
###############################################################################
# The communication module (communication.py)
###############################################################################
import cPickle
import socket
import struct
marshall = cPickle.dumps
unmarshall = cPickle.loads
def send(channel, *args):
buf = marshall(args)
value = socket.htonl(len(buf))
size = struct.pack("L",value)
channel.send(size)
channel.send(buf)
def receive(channel):
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = socket.ntohl(struct.unpack("L", size)[0])
except struct.error, e:
return ''
buf = ""
while len(buf) < size:
buf = channel.recv(size - len(buf))
return unmarshall(buf)[0]
到底是什么不起作用?你能给出一个小例子来说明哪里出了问题吗?我得到了这个结果:python telnet.py主机名端口。但是我无法启动聊天。你可以引用这个链接:啊,这就是输出?好吧,读一下,然后改变你的命令。必须将主机名和端口作为命令行参数。请尝试使用命令python telnet.py127.0.0.1 3490。我面临的错误如下:select.error所有这些都不是编程问题。你应该联系软件的作者,因为你显然不是自己写的。