python使用socket实现一对多通讯

最近在工作中遇到到了一对多的需求,大致就是目前有一个程式是运行在多台电脑上,每个电脑都会连接一个客户端进行通讯,现在打算将程式做成一对多的,从而可以只放置一台电脑就可以了。但是在一台电脑上就会出现一个程式要分别与多个客户端单独通讯,而且数据交互与显示必须在指定界面,因此我查询了一些资料,最后参考以下代码进行了修改,实现其功能,感谢博主

1.服务端代码如下:

from tkinter import *
from socket import *
import threading


address='127.0.0.1'
port=9000
buffsize=1024
s = socket(AF_INET, SOCK_STREAM)
s.bind((address,port))
s.listen(5)     #最大连接数
conn_list = []
conn_dt = {}

def tcplink(sock,addr):
    while True:
        try:
            recvdata=sock.recv(buffsize).decode('utf-8')
            print(recvdata, addr)
            gui.infoList.config(state=NORMAL)
            gui.infoList.insert(END, addr, 'name')
            gui.infoList.insert(END, ':\t')
            gui.infoList.insert(END, recvdata, 'conment')
            gui.infoList.insert(END, '\n\n')
            gui.infoList.config(state=DISABLED)
            if not recvdata:
                break
        except:
            sock.close()
            print(addr,'offline')
            _index = conn_list.index(addr)
            gui.listBox.delete(_index)
            conn_dt.pop(addr)
            conn_list.pop(_index)
            break

def recs():
    while True:
        clientsock,clientaddress=s.accept()
        if clientaddress not in conn_list:
            conn_list.append(clientaddress)
            conn_dt[clientaddress] = clientsock
            gui.listBox.insert(END, clientaddress)
        print('connect from:',clientaddress)
        #在这里创建线程,就可以每次都将socket进行保持
        t=threading.Thread(target=tcplink,args=(clientsock,clientaddress))
        t.start()


class GUI:
    def __init__(self, root):
        self.root = root
        self.leftFrame = Frame(self.root, width=20, height=30)
        self.leftFrame.grid(row=0, column=0)
        self.rightFrame = Frame(self.root, width=20, height=30)
        self.rightFrame.grid(row=0, column=1)
        Label(self.leftFrame, text='在线IP地址列表').grid(row=0, column=0)
        self.listBox = Listbox(self.leftFrame, width=15, height=10)
        self.listBox.grid(row=1, column=0)
        self.entry = Entry(self.rightFrame, font=('Serief', 18), width=30)
        self.entry.grid(row=0, column=0)
        self.sendBtn = Button(self.rightFrame, text='发送', command=self.send, width=10)
        self.sendBtn.grid(row=0, column=1)
        Label(self.rightFrame, text='聊天信息').grid(row=1, columnspan=2)
        self.infoList = Text(self.rightFrame, width=40, height=12)
        self.infoList.grid(row=2, columnspan=2)
        self.infoList.tag_config('name', background='yellow', foreground='red')
        self.infoList.tag_config('conment', background='black', foreground='white')


    def send(self):
        _index = self.listBox.curselection()
        conn_dt[self.listBox.get(_index)].sendall(self.entry.get().encode('utf-8'))
        self.entry.delete(0, END)

def createGUI():
    global gui
    root = Tk()
    gui = GUI(root)
    root.title('服务器')
    root.mainloop()

if __name__ == '__main__':
    t1 = threading.Thread(target=recs, args=(), name='rec')
    t2 = threading.Thread(target=createGUI, args=(), name='GUI')

    t1.start()
    t2.start()

2.客户端代码如下:

from socket import *
import threading
from tkinter import *

address='127.0.0.1'   #服务器的ip地址
port=9000
buffsize=1024
s=socket(AF_INET, SOCK_STREAM)
s.connect((address,port))



def recv():
    while True:
        recvdata = s.recv(buffsize).decode('utf-8')
        gui.listBox.insert(END, recvdata)
        print('\n' + recvdata + '\n')

class GUI:
    def __init__(self, root):
        self.root = root
        self.listBox = Listbox(self.root)
        self.listBox.pack()
        self.entry = Entry(self.root)
        self.entry.pack()
        self.sendBtn = Button(self.root, text='发送', command=self.send)
        self.sendBtn.pack()

    def send(self):
        senddata = self.entry.get()
        s.send(senddata.encode())

def createGUI():
    global gui
    root = Tk()
    gui = GUI(root)
    root.title('客户端')
    root.mainloop()

if __name__ == '__main__':
    t1 = threading.Thread(target=recv, args=(), name='recv')
    t2 = threading.Thread(target=createGUI, args=(), name='gui')

    t1.start()
    t2.start()

再次感谢博主,附上原文链接如下:
https://www.cnblogs.com/liyang93/p/9117387.html

  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值