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

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

服务器:#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

标签:Python,socket,全双工,通信
0
投稿

猜你喜欢

  • python读取pdf格式文档的实现代码

    2023-12-10 07:25:49
  • python相似模块用例

    2023-02-05 12:04:09
  • 百度百科中的asp词条:什么是asp

    2008-10-11 14:38:00
  • python中用ggplot绘制画图实例讲解

    2023-07-04 07:25:16
  • 利用python做数据拟合详情

    2023-04-22 15:32:17
  • 使用AJAX的一个简单的例子

    2007-09-21 17:55:00
  • layui 上传文件_批量导入数据UI的方法

    2024-05-22 10:36:41
  • Python实现的质因式分解算法示例

    2021-12-16 23:10:05
  • python实现指定文件夹下的指定文件移动到指定位置

    2023-07-03 08:21:11
  • Python代码列表求并集,交集,差集

    2021-12-03 03:33:38
  • 详解Windows Server 2012下安装MYSQL5.7.24的问题

    2024-01-27 10:20:37
  • Python编程实现tail-n查看日志文件的方法

    2023-07-26 01:17:42
  • python进阶之协程你了解吗

    2022-11-04 19:04:48
  • 微信小程序技巧之show内容展示,上传文件编码问题

    2023-09-23 07:25:30
  • 基于python获取本地时间并转换时间戳和日期格式

    2021-02-23 17:30:06
  • 查看django执行的sql语句及消耗时间的两种方法

    2021-03-28 13:33:48
  • Python实现的摇骰子猜大小功能小游戏示例

    2022-04-08 13:26:28
  • 几个优化WordPress中JavaScript加载体验的插件介绍

    2023-11-03 12:03:08
  • Python使用Kubernetes API访问集群

    2023-09-23 05:35:31
  • Vue中的Object.defineProperty全面理解

    2024-05-29 22:44:02
  • asp之家 网络编程 m.aspxhome.com