网络编程
位置:首页>> 网络编程>> Python编程>> Python socket实现多对多全双工通信的方法

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

作者:小銍  发布时间:2023-05-02 17:31:38 

标签:Python,socket,全双工,通信

服务器:#server.py


#!/usr/bin/env python
#-*-coding:utf-8-*-
import sys
import 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,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()

来源:https://blog.csdn.net/zhidetian/article/details/53470849

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com