美文网首页
局域网广播

局域网广播

作者: f5423d3134f0 | 来源:发表于2020-09-27 17:09 被阅读0次

转载:https://www.cnblogs.com/noright/p/python-socket-broadcast.html

#!/usr/bin/env python3

import time
import threading
import queue
import socket

# 三个线程:
# 线程1:产生递增的数字,转成字符串放到队列中
# 线程2:监听端口,将产生的连接放到列表中
# 线程3:从队列中取出数字,遍历连接列表,发送到所有客户端

# 线程1:产生递增的数字,转成字符串放到队列中
class Producer(threading.Thread):

    def __init__(self, work_queue):
        super().__init__() # 必须调用
        self.work_queue = work_queue
        
    def run(self):
        #print("Begin produce...")
        num = 1
        while True:
            self.work_queue.put(str(num))
            num = num+1
            time.sleep(1) # 暂停1秒

# 线程2:监听端口,将产生的连接放到列表中
class SocketServer(threading.Thread):

    def __init__(self, socket_list):
        super().__init__()
        self.socket_list = socket_list

    def run(self):
        sock = socket.socket()
        sock.bind(('', 9090))
        sock.listen(5)
        print("Start listen...")
        while True:
            conn, addr = sock.accept()
            print("Connect by", addr)
            self.socket_list.append((conn, addr))


# 线程3:从队列中取出数字,遍历连接列表,发送到所有客户端
class Printer(threading.Thread):

    def __init__(self, work_queue, socket_list):
        super().__init__() # 必须调用
        self.work_queue = work_queue
        self.socket_list = socket_list

    def run(self):
        while True:
            num = self.work_queue.get() # 当队列为空时,会阻塞,直到有数据
            for sock, addr in self.socket_list: # 遍历保存连接的列表
                print("Send", num, "To", addr)
                try:
                    sock.sendall(bytes(num + '\r\n', 'utf-8')) # 把字符串转换成字节数组发送
                except:
                    print("Disconnect by", addr) # 如果连接断开,发送会失败
                    self.socket_list.remove((sock, addr)) # 从列表中删除断开的连接

def main():
    work_queue = queue.Queue()
    socket_list = [] # 为了更安全可靠,从多线程访问列表时应该加锁,
                     # 这里做了简化,因为列表的增加删除操作基本上可以认为是线程安全的

    socket_server = SocketServer(socket_list)
    socket_server.daemon = True
    socket_server.start()

    printer = Printer(work_queue, socket_list)
    printer.daemon = True # 当主线程退出时子线程也退出
    printer.start()

    producer = Producer(work_queue)
    producer.daemon = True # 当主线程退出时子线程也退出
    producer.start()

    time.sleep(1) # 这里要暂停一下,否则执行下一条语句时,会因队列为空而直接返回
    work_queue.join() # 主线程会停在这里,直到所有数字被get(),并且task_done(),因为没有调用task_done(),所在这里会一直阻塞,直到用户按^C

if __name__ == '__main__':
    main()

相关文章

  • 数据链路层(二)

    一、使用广播信道的数据链路层 广播信道可以进行一对多的通信,因此使用广播信道的局域网被称为共享式局域网。现在具有更...

  • 局域网广播

    转载:https://www.cnblogs.com/noright/p/python-socket-broadc...

  • 实时Android语音对讲系统架构

    本文属于Android局域网内的语音对讲项目系列,《通过UDP广播实现Android局域网Peer Discove...

  • Lan和Vlan的区别和原理

    一、LAN 本地局域网 LAN 表示 Local Area Network,本地局域网。一个 LAN 表示一个广播...

  • 第七天

    1、协议 1.1、链路层 网卡---> mac地址处理 广播风暴 1.2 网络层 广播只在当前局域网有效 IP--...

  • Socket 进行UDP广播数据(GCDAsyncUdpSock

    在做一个App的时候,有一个需求是服务端在局域网当中发送广播数据,然后连接到此局域网当中的客户端接收到广播数据后,...

  • Socket 进行UDP广播数据(GCDAsyncUdpSock

    在做一个App的时候,有一个需求是服务端在局域网当中发送广播数据,然后连接到此局域网当中的客户端接收到广播数据后,...

  • 网络技术与应用

    第四章 局域网原理 一、局域网概述 二、以太网技术 三、局域网的扩展 以太网的级联与扩展 冲突域 广播域 集线器 ...

  • VLAN基础配置及access接口

    原理概述: 为了避免冲突域,拓展局域网接入更多的PC,在局域网中使用二层交换机,能有效各隔离冲突域。 为了减少广播...

  • 虚拟局域网技术——VLAN

    虚拟局域网工程应用需求 在我们的网络中为什么要用到vlan这个技术?1、局域网需要隔离广播这种需求交换机接收到一个...

网友评论

      本文标题:局域网广播

      本文链接:https://www.haomeiwen.com/subject/qjqluktx.html