首页 > 编程 > Python > 正文

Python socket实现多对多全双工通信的方法

2019-11-25 13:18:12
字体:
来源:转载
供稿:网友

服务器:#server.py

#!/usr/bin/env python#-*-coding:utf-8-*-import sysimport struct#将字符串打包为二进制流进行网络传输import select#import signal#用于捕获中断信号import cPickle#将python对象进行序列化:dumps将python对象序列化保存为字符串,loads与之相反from socket import *HOST = ''def send(channel,*args):#发送数据  buffer = cPickle.dumps(args)  value = htonl(len(buffer))  size = struct.pack("L",value)  channel.send(size)  channel.send(buffer)def receive(channel):#接收数据  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]#恢复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中断进程(ctrl+c), SIGTERM 终止进程,SIGKILL杀死进程,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:#服务器端接收          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,receivefrom socket import *import sysimport selectimport cPickleimport structimport 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()        breakif __name__ == "__main__":  name = raw_input("Please input login name > ")  client=ChatClient(name)  client.run()

以上这篇Python socket实现多对多全双工通信的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表