python socket双向通信_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()

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!非常感谢您的问题。在python实现全双工聊天可以使用socket库来完成。具体的步骤如下: 1. 创建一个socket对象,并绑定要监听的IP地址和端口号。 2. 使用listen()方法开始监听传入连接请求。 3. 使用accept()方法接受客户端的连接请求,并为每个客户端创建一个新的线程来处理客户端请求。 4. 在每个客户端线程中,使用recv()方法从客户端接收数据,并使用send()方法向客户端发送响应数据。 以下是一个简单的Python全双工聊天示例代码: ``` import socket import threading # 定义要监听的IP地址和端口号 HOST = '0.0.0.0' PORT = 8000 # 创建socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((HOST, PORT)) server_socket.listen(5) print(f"Server started, listening on {HOST}:{PORT}") # 定义处理客户端请求的函数 def handle_client(client_socket): while True: # 接收客户端发送的数据 data = client_socket.recv(1024).decode('utf-8') print(f"Received message: {data}") if data.strip() == 'quit': # 如果收到quit命令则关闭客户端连接 client_socket.close() print(f"Client disconnected.") break # 向客户端发送响应数据 response = f"Received message: {data}" client_socket.send(response.encode('utf-8')) while True: # 等待客户端连接请求 client_socket, client_address = server_socket.accept() print(f"Client connected from {client_address}") # 创建新线程处理客户端请求 client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start() ``` 上述代码实现了一个简单的全双工聊天程序,当有客户端连接时,会创建一个新的线程处理客户端请求,线程会在接收到客户端消息后打印消息内容,并向客户端发送响应消息。当客户端发送quit命令时,线程会关闭客户端连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值