一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Python簡單的多客戶端聊天室程序

 看風(fēng)景D人 2014-01-08

本文所示代碼將教你如何使用Python標(biāo)準(zhǔn)庫中的select.select模塊實現(xiàn)多路復(fù)用的命令行下CS模式的聊天室程序。

服務(wù)器端代碼:

復(fù)制代碼
#!/usr/bin/env python

"""
A basic, multiclient 'chat server' using Python's select module
with interrupt handling.

Entering any input at the terminal will exit the server.
"""

import select
import socket
import sys
import signal
from communication import send, receive

BUFSIZ = 4096


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()
復(fù)制代碼

客戶端代碼:

復(fù)制代碼
#! /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()
復(fù)制代碼

communication模塊代碼:

復(fù)制代碼
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]
復(fù)制代碼

(完全完)


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产精品涩涩成人一区二区三区 | 日韩亚洲激情在线观看| 丁香七月啪啪激情综合| 色哟哟国产精品免费视频| 欧美中文日韩一区久久| 欧美一区二区三区视频区| 好东西一起分享老鸭窝| 国产日产欧美精品视频| 亚洲中文字幕视频在线播放| 亚洲一区二区精品免费视频| 午夜福利精品视频视频| 儿媳妇的诱惑中文字幕| 女厕偷窥一区二区三区在线| 麻豆剧果冻传媒一二三区| 久热这里只有精品九九| 午夜精品福利视频观看| 成人精品一级特黄大片| 亚洲国产精品一区二区毛片| 伊人久久青草地婷婷综合| 91国内视频一区二区三区| 丰满少妇被猛烈撞击在线视频| 加勒比日本欧美在线观看| 日韩欧美一区二区不卡看片| 99久免费精品视频在线观| 欧美综合色婷婷欧美激情| 尤物天堂av一区二区| 午夜福利视频偷拍91| 亚洲欧美日韩综合在线成成| 欧美做爰猛烈叫床大尺度| 国产精品一区二区香蕉视频| 激情中文字幕在线观看| 国产精品视频久久一区| 亚洲欧美日韩在线看片| 亚洲中文在线观看小视频| 麻豆欧美精品国产综合久久| 妻子的新妈妈中文字幕| 日韩丝袜诱惑一区二区| 大香伊蕉欧美一区二区三区| 日本少妇中文字幕不卡视频| 国产精品一区二区视频成人| 欧美一区二区三区播放|