Python socket實(shí)現(xiàn)多對多全雙工通信的方法
更新時間:2019年02月13日 10:33:49 作者:小銍
今天小編就為大家分享一篇Python socket實(shí)現(xiàn)多對多全雙工通信的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
服務(wù)器:#server.py
#!/usr/bin/env python
#-*-coding:utf-8-*-
import sys
import struct#將字符串打包為二進(jìn)制流進(jìn)行網(wǎng)絡(luò)傳輸
import select#
import signal#用于捕獲中斷信號
import cPickle#將python對象進(jìn)行序列化:dumps將python對象序列化保存為字符串,loads與之相反
from socket import *
HOST = ''
def send(channel,*args):#發(fā)送數(shù)據(jù)
buffer = cPickle.dumps(args)
value = htonl(len(buffer))
size = struct.pack("L",value)
channel.send(size)
channel.send(buffer)
def receive(channel):#接收數(shù)據(jù)
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = ntohl(struct.unpack("L",size)[0])#socket.ntohl(參考:http://blog.csdn.net/tatun/article/details/7194973)
except struct.error,e:
return ''
buf = ''
while len(buf) < size:
buf += channel.recv(size-len(buf))
return cPickle.loads(buf)[0]#恢復(fù)python對象
class ChatServer(object):
def __init__(self,PORT,backlog = 5):
self.clients = 0
self.clientmap = {}
self.outputs = [] #Client會話列表
self.server = socket(AF_INET, SOCK_STREAM)
self.server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#重用套接字地址
self.server.bind((HOST,PORT))
self.server.listen(backlog)
signal.signal(signal.SIGINT,self.signalhandler)#使用signal模塊捕獲中斷操作 SIGINT中斷進(jìn)程(ctrl+c), SIGTERM 終止進(jìn)程,SIGKILL終止進(jìn)程,SIGALRM 鬧鐘信號
def signalhandler(self,signum,frame):#中斷處理方法
print "Shutting down server ..."
for output in self.outputs:
output.close()
self.server.close()
def get_client_name(self,client):
info = self.clientmap[client]
host,port,name = info[0][0],info[0][1],info[1]
return ':'.join((('@'.join((name,host))),str(port)))
def run(self):
inputs = [self.server]
print 'Waiting for connect...'
while True:
try:
readable,writeable,execption = select.select(inputs,self.outputs,[])
except select.error,e:
break
for sock in readable:
if sock == self.server:#服務(wù)器端接收
client,address = self.server.accept()
print "Chat server: connected from",address
self.clients += 1
cname = receive(client)
send(client,str(address[0]))
inputs.append(client)
self.clientmap[client] = (address,cname)
msg = "(Connected : New Client(%d) from %s)\n"%(self.clients,self.get_client_name(client))
message = "At present, only one of you is in the chat room!"
if self.clients == 1:
send(client,message)
for output in self.outputs:
send(output,msg)
self.outputs.append(client)#將開始回話的client加入Client回話列表
#elif sock == sys.stdin:
#break
else:
try:
data = receive(sock)
if data:
msg = '[' + self.get_client_name(sock)+ '] >> ' + data
for output in self.outputs:
if output!=sock:
send(output,msg)
else:
self.clients-=1
sock.close()
inputs.remove(sock)
self.outputs.remove(sock)
msg = '(Now hung up: Client from %s)'%self.get_client_name(sock)
message = "At present, only one of you is in the chat room!"
for output in self.outputs:
send(output,msg)
if self.clients == 1:
send(self.outputs[0],message)
except error,e:
inputs.remove(sock)
self.outputs.remove(sock)
self.server.close()
if __name__ == "__main__":
server = ChatServer(6004)
server.run()
客戶端:#client.py
#!/usr/bin/env python
#-*-coding:utf-8-*-
from server import send,receive
from socket import *
import sys
import select
import cPickle
import struct
import signal
class ChatClient(object):
def __init__(self,name):
self.name = name
self.connected = False
self.host = 'localhost'
self.port = 6004
try:
self.sock = socket(AF_INET,SOCK_STREAM)
self.sock.connect((self.host,self.port))
self.connected = True
send(self.sock,self.name)
data= receive(self.sock)
addr = data
except error,e:#socket.serro
print 'Failed to connect to chat server'
sys.exit(1)
def run(self):
while True:
try:
readable,writeable,exception = select.select([0,self.sock],[],[])
for sock in readable:
if sock == 0:
data = sys.stdin.readline().strip()
if data:
send(self.sock,data)
else:
data=receive(self.sock)
if not data:
print 'Client shutting down.'
self.connected = False
break
else:
sys.stdout.write(data+'\n')
sys.stdout.flush()
except KeyboardInterrupt:
print 'Client interrupted'
self.sock.close()
break
if __name__ == "__main__":
name = raw_input("Please input login name > ")
client=ChatClient(name)
client.run()
以上這篇Python socket實(shí)現(xiàn)多對多全雙工通信的方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python應(yīng)用程序在windows下不出現(xiàn)cmd窗口的辦法
這篇文章主要介紹了python應(yīng)用程序在windows下不出現(xiàn)cmd窗口的辦法,適用于python寫的GTK程序并用py2exe編譯的情況下,需要的朋友可以參考下2014-05-05
django使用admin站點(diǎn)上傳圖片的實(shí)例
今天小編就為大家分享一篇django使用admin站點(diǎn)上傳圖片的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
python實(shí)現(xiàn)數(shù)組平移K位問題
這篇文章主要介紹了python實(shí)現(xiàn)數(shù)組平移K位問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
python3中os.path模塊下常用的用法總結(jié)【推薦】
這篇文章主要介紹了python3中os.path模塊下常用的用法總結(jié) ,需要的朋友可以參考下2018-09-09
TensorFlow實(shí)現(xiàn)Softmax回歸模型
這篇文章主要介紹了TensorFlow實(shí)現(xiàn)Softmax回歸模型,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03

