天道酬勤,学无止境

Python端口转发/多路复用服务器(Python port forwarding/multiplexing server)

问题

我想让服务器侦听 UDP 端口 162(SNMP 陷阱),然后将此流量转发给多个客户端。 同样重要的是源端口和地址保持不变(地址欺骗)。

我想最好的工具是 Twisted 或 Scapy 或者可能是香草套接字,只是我在 Twisted 的文档中找不到关于源地址欺骗/伪造的任何内容。

有什么解决办法吗?

编辑:增加了赏金,我的 iptables 有什么解决方案吗?

回答1

我对 Twisted 或 scapy 不满意,但是使用 vanilla python 套接字执行此操作非常简单。 这样做的另一个好处是它会更加便携。 此代码适用于我的有限测试:

#!/usr/bin/python
from socket import *
bufsize = 1024 # Modify to suit your needs
targetHost = "somehost.yourdomain.com"
listenPort = 1123

def forward(data, port):
    print "Forwarding: '%s' from port %s" % (data, port)
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(("localhost", port)) # Bind to the port data came in on
    sock.sendto(data, (targetHost, listenPort))

def listen(host, port):
    listenSocket = socket(AF_INET, SOCK_DGRAM)
    listenSocket.bind((host, port))
    while True:
        data, addr = listenSocket.recvfrom(bufsize)
        forward(data, addr[1]) # data and port

listen("localhost", listenPort)
回答2

接受的答案对我不起作用,我最终在 python 中使用了一个简单的 TCP 重定向器:

#!/usr/bin/env python

import socket
import threading
import select
import sys

terminateAll = False

class ClientThread(threading.Thread):
    def __init__(self, clientSocket, targetHost, targetPort):
        threading.Thread.__init__(self)
        self.__clientSocket = clientSocket
        self.__targetHost = targetHost
        self.__targetPort = targetPort

    def run(self):
        print "Client Thread started"

        self.__clientSocket.setblocking(0)

        targetHostSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        targetHostSocket.connect((self.__targetHost, self.__targetPort))
        targetHostSocket.setblocking(0)

        clientData = ""
        targetHostData = ""
        terminate = False
        while not terminate and not terminateAll:
            inputs = [self.__clientSocket, targetHostSocket]
            outputs = []

            if len(clientData) > 0:
                outputs.append(self.__clientSocket)

            if len(targetHostData) > 0:
                outputs.append(targetHostSocket)

            try:
                inputsReady, outputsReady, errorsReady = select.select(inputs, outputs, [], 1.0)
            except Exception, e:
                print e
                break

            for inp in inputsReady:
                if inp == self.__clientSocket:
                    try:
                        data = self.__clientSocket.recv(4096)
                    except Exception, e:
                        print e

                    if data != None:
                        if len(data) > 0:
                            targetHostData += data
                        else:
                            terminate = True
                elif inp == targetHostSocket:
                    try:
                        data = targetHostSocket.recv(4096)
                    except Exception, e:
                        print e

                    if data != None:
                        if len(data) > 0:
                            clientData += data
                        else:
                            terminate = True

            for out in outputsReady:
                if out == self.__clientSocket and len(clientData) > 0:
                    bytesWritten = self.__clientSocket.send(clientData)
                    if bytesWritten > 0:
                        clientData = clientData[bytesWritten:]
                elif out == targetHostSocket and len(targetHostData) > 0:
                    bytesWritten = targetHostSocket.send(targetHostData)
                    if bytesWritten > 0:
                        targetHostData = targetHostData[bytesWritten:]

        self.__clientSocket.close()
        targetHostSocket.close()
        print "ClienThread terminating"

if __name__ == '__main__':
    if len(sys.argv) != 5:
        print 'Usage:\n\tpython SimpleTCPRedirector <host> <port> <remote host> <remote port>'
        print 'Example:\n\tpython SimpleTCPRedirector localhost 8080 www.google.com 80'
        sys.exit(0)     

    localHost = sys.argv[1]
    localPort = int(sys.argv[2])
    targetHost = sys.argv[3]
    targetPort = int(sys.argv[4])

    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serverSocket.bind((localHost, localPort))
    serverSocket.listen(5)
    print "Waiting for client..."
    while True:
        try:
            clientSocket, address = serverSocket.accept()
        except KeyboardInterrupt:
            print "\nTerminating..."
            terminateAll = True
            break
        ClientThread(clientSocket, targetHost, targetPort).start()

    serverSocket.close()
回答3

转发端口的一种不同但相关的解决方案,而不是多路复用(不回答具体问题,但希望匹配相关问题 - 这至少是我正在寻找的):

http://www.linux-support.com/cms/forward-network-connections-with-python/

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • day21 网络编程(下)
    day21 网络编程(下) 版权声明:本博客转载自路飞学城Python全栈开发培训课件,仅用于学习之用,严禁用于商业用途。 欢迎访问路飞学城官网:https://www.luffycity.com/ 课程目标:学会网络编程开发的必备知识点。 今日概要: OSI7 层模型TCP和UDP粘包阻塞和非阻塞IO多路复用 1. OSI 7层模型 OSI的7层模型对于大家来说可能不太好理解,所以我们通过一个案例来讲解: 假设,你在浏览器上输入了一些关键字,内部通过DNS找到对应的IP后,再发送数据时内部会做如下的事: 应用层:规定数据的格式。 "GET /s?wd=你好 HTTP/1.1\r\nHost:www.baidu.com\r\n\r\n" 表示层:对应用层数据的编码、压缩(解压缩)、分块、加密(解密)等任务。 "GET /s?wd=你好 HTTP/1.1\r\nHost:www.baidu.com\r\n\r\n你好".encode('utf-8') 会话层:负责与目标建立、中断连接。 在发送数据之前,需要会先发送 “连接” 的请求,与远程建立连接后,再发送数据。当然,发送完毕之后,也涉及中断连接的操作。 传输层:建立端口到端口的通信,其实就确定双方的端口信息。 数据:"GET /s?wd=你好 HTTP/1.1\r\nHost:www.baidu.com\r\n\r\n你好"
  • Python port forwarding/multiplexing server
    I would like to make server that listen on UDP port 162 (SNMP trap) and then forwards this traffic to multiple clients. Also important is that the source port & address stays same (address spoofing). I guess that best tool for this would be Twisted or Scapy or maybe vanilla sockets, only I can't find anything in the documentation for Twisted about source address spoofing/forging. Any solution for this? Edit:added bounty, mybe any solution with iptables?
  • 思科认证CCNA专业英文词汇全集(3)
    data circuit-terminating equipment (数据电路终接设备)----- DCE用来间DTE设备提供定时。 data compression (数据压缩)----- 参见compression。 data direct VCC (数据直接VCC)----- ATM中两个LEG之间建立的一个双向点到点虚拟控制连接(VCC),是由Phase 1 LAN仿真定义的三个数据连接之一。因为数据直接VCC并不保证QoS,它们通常被留做UBR和ABR连接。对比control distribute VCC和control direct VCC。 data encapsulation (数据封装)----- 一个协议中的信息在另一个协议的数据部分中被包装或包含的过程。在OSI参考模型中,数据向下流过协议栈时,每一层封装紧接它的上一层。 data frame (数据帧)----- OSI参考模型数据链路层上的协议数据单元封装。从网络层封装数据包并为在网络介质上传输准备数据。 datagram (数据报)----- 作为网络层单元无需预先建立虚电路并在介质上传输的一个信息的逻辑集合。IP数据报已经成为因特网的主要的信息单元。在OSI参考模型的各层,术语信元(cell)、帧 (frame)、报文 (message)和段 (segment)也定义这些逻辑信息分组。 Data
  • HCIA复习总结
    HCIA复习总结 OSI : 开放式系统互联(参考模型) 应用层,表示层,会话层-----控制层面 传输层,网络层,数据链路层,物理层----数据层面 分层的思想 应用层:接收用户的数据,人机交互的接口,面向的应用程序。 表示层:将逻辑语言(软件语言)转换为机器语言(二进制语言),翻译 ,加密 会话层:针对传输的每一种数据(流量)建立(管理:维持、终止)一条虚连接(为了防止不同类型的数据互相影 响) 传输层:作用 1.区分流量 2.定义数据传输方式 网络层: 基于网络层地址(IP地址)进行不同网络系统间的路径选择 数据链路层 : 在物理层上建立、撤销、标识逻辑链接和链路复用 以及差错校验等功能。通过使用接收系统的硬件地址或物理地址来寻址 物理层: 建立、维护和取消物理连接 TCP:传输控制协议,是一种面向连接的可靠传输协议 UDP:用户数据报协议,是一种非面向连接的不可靠传输协议 三次握手: 保证了面向连接 ,又称为TCP的三次握手 路由器:三层设备,识别IP地址。不同的接口在不同的网段(广播域) 交换机(网桥):二层设备,使用MAC地址,所有的接口默认在同一个广播域,一个接口是一个冲突域。 集线器(hub):放大器 放大信号,属于1层设备,识别bit流,hub上所有的接口都在同一个冲突域中。 DHCP DHCP: Dynamic Host Configration
  • 计算机网络数据链路层复习框架及易错题
    概念 在物理层所提供服务的基础上向网络层提供服务。即:将原始的,有差错的物理线路改进成逻辑上无差错的数据链路。 基本服务 无确认的无连接服务、有确认的无连接服务、有确认的有连接服务 功能 链路管理:负责数据链路的建立、维持和释放,主要用于面向连接服务。帧同步:接收方确定收到的比特流中一帧的开始位置和结束位置。差错控制:用于使接收方确定收到的数据就是由发送方发送的数据。透明传输: 组帧 字符计数法:一个特殊字符表示一帧的开始;一个计数字段(提供的字节数包含自身所占的一个字节)表示该帧包含的字节数。字节填充的首尾界符法:首部SOH(start of header)十六进制数为01,尾部EOT(end of transmission)十六进制数为04,当中间的数据部分出现首字符SOH转变为ESC x,出现尾字符EOT转变为ESC y,出现转义符ESC转变为ESC z。比特填充的首尾标志法:开始结束标志均为01111110,当数据部分出现开始结束标志时,发送方在每5个连续的1后添一个0,接收方在每5个连续的1后删除一个0。物理编码违例法:利用物理介质上编码的违法标志来区分帧的开始与结束。 差错控制 检错编码:1.奇偶校验码;2. 循环冗余码:具有r检测位的多项式能够检测出所有小于或等于r的突发错误。纠错编码:海明码 流量控制 目的:控制发送方发送数据的速率,使接收方来得及接收。方法
  • Python自动选择串行端口(对于Arduino)(Python to automatically select serial ports (for Arduino))
    问题 当前,Python程序必须知道设备(Arduino)处于哪个端口上,然后Python才能与该设备通信。 问题:无论何时插入设备并重新插入,其COM端口都会更改,因此必须再次将正确的串行端口提供给Python,以便它可以找到设备。 Python(使用pySerial )如何自动搜索要使用的正确串行端口? python是否可以将串行端口上的设备正确识别为Arduino? 回答1 使用以下代码查看所有可用的串行端口: import serial.tools.list_ports ports = list(serial.tools.list_ports.comports()) for p in ports: print p 这给了我以下内容: ('COM4', 'Arduino Due Programming Port (COM4)', 'USB VID:PID=2341:003D SNR=75330303035351300230') ('COM11', 'RS-232 Port (COM11)', 'FTDIBUS\\VID_0856+PID_AC27+BBOPYNPPA\\0000') 要确定它是否是Arduino,可以执行以下操作: if "Arduino" in p.description: print "This is an Arduino!" 回答2 使用serial
  • 如何在Cygwin中使用COM和USB端口?(How can I use COM and USB ports within Cygwin?)
    问题 我想使用Python脚本从Arduino板发送/接收数据。 我想使用Python及其似乎适合我的pySerial模块来做到这一点。 所以我在cygwin(后面的Windows XP)中安装了Python和pySerial。 Python脚本非常简单: $ cat example.py #print "testing my COM26 port using python" import serial ser = serial.Serial() ser.baudrate = 9600 ser.port = 26 ser ser.open() ser.isOpen() 但是,在运行时,出现以下错误。 $ python example.py Traceback (most recent call last): File "example.py", line 9, in <module> ser.open() File "/usr/lib/python2.5/site-packages/serial/serialposix.py", line 276, in open raise SerialException("could not open port %s: %s" % (self._port, msg)) serial.serialutil.SerialException
  • Python中的虚拟串行设备?(Virtual Serial Device in Python?)
    问题 我知道我可以使用pySerial与串行设备进行通讯,但是如果我现在没有设备,但仍需要为其编写客户端,该怎么办? 我如何用Python编写“虚拟串行设备”并进行pySerial对话,就像运行本地Web服务器一样? 也许我只是搜索不好,但一直找不到有关此主题的任何信息。 回答1 到目前为止,这是我所做的并为我完成的工作: import os, pty, serial master, slave = pty.openpty() s_name = os.ttyname(slave) ser = serial.Serial(s_name) # To Write to the device ser.write('Your text') # To read from the device os.read(master,1000) 如果创建更多的虚拟端口,则不会有问题,因为即使不同的主设备具有相同的名称,它们也会获得不同的文件描述符。 回答2 使用com0com之类的东西(如果您使用的是Windows)可能更容易设置虚拟串行端口并在其上进行开发。 回答3 我可以使用以下代码模拟任意串行端口./foo : SerialEmulator.py import os, subprocess, serial, time # this script lets you emulate a serial
  • 计算机网络名词解释知识点简答题整理
    名词解释: 基带传输:比特流直接向电缆发送,无需调制到不同频段;基带信号:信源发出的没有经过调制的原始电信号;URL:统一资源定位符,标识万维网上的各种文档,全网范围唯一;传输时延:将分组的所有比特推向链路所需要的时间;协议:协议是通信设备通信前约定好的必须遵守的规则与约定,包括语法、语义、定时等。网络协议:对等层中对等实体间制定的规则和约定的集合;MODEM:调制解调器;起始(原始)服务器:对象最初存放并始终保持其拷贝的服务器;计算机网络:是用通信设备和线路将分散在不同地点的有独立功能的多个计算机系统互相连接起来,并通过网络协议进行数据通信,实现资源共享的计算机集合;解调:将模拟信号转换成数字信号;多路复用:在一条传输链路上同时建立多条连接,分别传输数据;默认路由器:与主机直接相连的一台路由器;LAN:局域网,是一个地理范围小的计算机网络;DNS:域名系统,完成主机名与IP地址的转换;ATM:异步传输模式,是建立在电路交换和分组交换基础上的一种面向连接的快速分组交换技术;Torrent:洪流,参与一个特定文件分发的所有对等方的集合;Cookie:为了辨别用户、用于session跟踪等而储存在用户本地终端的数据;SAP:服务访问点;n PDU:PDU为协议数据单元,指对等层之间的数据传输单位;第n层的协议数据单元;PPP:点对点传输协议;Web caching:网页缓存技术;Web
  • 华为模拟器eNSP配置NAT网络实验
    NAT(Network Address Translation,网络地址转换) 首先了解现在IP地址的使用情况,私有 IP 地址是指内部网络或主机的IP 地址,公有IP 地址是指在因特网上全球唯一的IP 地址。RFC 1918 为私有网络预留出了三个IP 地址块,如下: A 类:10.0.0.0~10.255.255.255 B 类:172.16.0.0~172.31.255.255 C 类:192.168.0.0~192.168.255.255 NAT技术缓解了当前互联网IPV4地址匮乏的情况 NAT的实现方式有三种,即静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。 静态转换是指将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一成不变的,某个私有IP地址只转换为某个公有IP地址。借助于静态转换,可以实现外部网络对内部网络中某些特定设备(如服务器)的访问。 动态转换是指将内部网络的私有IP地址转换为公用IP地址时,IP地址是不确定的,是随机的,所有被授权访问上Internet的私有IP地址可随机转换为任何指定的合法IP地址。也就是说,只要指定哪些内部地址可以进行转换,以及用哪些合法地址作为外部地址时,就可以进行动态转换。动态转换可以使用多个合法外部地址集。当ISP提供的合法IP地址略少于网络内部的计算机数量时
  • WebRTC SDP 详解和剖析
    WebRTC 是 Web Real-Time Communication,即网页实时通信的缩写,是 RTC 协议的一种 Web 实现,项目由 Google 开源,并和 IETF 和 W3C 制定了行业标准。在国内 WebRTC 已经获得了越来越多厂商的支持,应用前景变得更加广阔,所以我们也开设专栏,分享阿里云内部的 WebRTC 研究工作。 本篇是阿里云视频云 WebRTC 技术专栏系列文章的第一篇,作者将从 WebRTC SDP 例子和关键属性的角度为大家深度剖析解读,其中也分享了阿里云技术专家的一些实践经验,希望能对大家有所帮助或者启发。后续 WebRTC 技术专栏系列将继续推出 WebRTC ICE/DTLS/SRTP/RTCP/TURN 的详解与剖析,欢迎关注我们的公众号。 作者:忘篱,阿里云高级技术专家,负责阿里云 RTC 服务器研发;泰一,阿里云高级开发工程师,从事阿里云 RTC 服务器研发 Overview 狭义的说 WebRTC 是指浏览器端,浏览器端如何直接交换数据呢?肯定是没法完全独立完成的,必须得依靠服务器。一般依赖几种服务器: Signaling 信令服务器,也就是交换房间和会议的媒体信息,以及会议期间的消息,媒体描述使用的是 SDP 协议,也就是本文剖析的重点。 ICE 服务器,可以分为帮助两个客户端打洞建立 P2P 连接的 STUN 服务器
  • NAT功能详解及案例分析—华为NAT server的实现
    NAT #network address translation - 网络地址转换。 NAT的分类 #静态NAT、动态NAT,动态NAT包含了我们常用的PNAT(PAT)。 端口nat (端口地址转换 华为&思科NAT对比 静态NAT #静态转换是指将内部网络的私有IP地址转换为公有IP地址, IP地址对是一对一的,是一成不变的,某个私有IP地址只转换为某个公有IP地址。 借助于静态转换,可以实现外部网络对内部网络中某些特定设备(如服务器)的访问。 动态NAT #内部网络的私有IP地址转换为公用IP地址时,IP地址是不确定的, 是随机的,所有被授权访问上Internet的私有IP地址可随机转换为任何指定的合法IP地址。 端口多路复用 (Port address Translation,PAT):#即端口地址转换(PAT,Port Address Translation).采用端口多路复用方式。内部网络的所有主机均可共享一个合法外部IP地址实现对Internet的访问,从而可以最大限度地节约IP地址资源。同时,又可隐藏网络内部的所有主机,有效避免来自internet的***。因此,目前网络中应用最多的就是端口多路复用方式。 NAT的作用 #作用是实现内网私有IP地池与外网公有IP地址的转换,从而实现内网与外网的互通。 同时还可以隐藏内部网络的结构,增强网络的安全性。 静态NAT配置
  • 专业课问答
    2. TCP与UDP的连接区别及适用情况 3. 路由和交换的区别 4. 七层网络结构 物理层 数据链路层(PPP、HDLC、CSMA/CD) 网络层(IP、ARP(IP→MAC)/RARP(MAC→IP)、ICMP) 传输层(TCP、UDP) 会话层 表示层 应用层(telnet 23、FTP 20<数据>+21<控制>、SMTP 161、DNS、SNMP、DHCP、HTTP 80) TCP/IP是四层(网络接口层、网际层、运输层、应用层) 5. 时分复用的时隙 6. IPV4和IPV6的位数 IPV4是32位;IPV6是128位 7. 单工、半双工、全双工 单工:又称为单向通信,即只能有一个方向的通信而没有反方向的交互。例:无线电广播,电视广播 半双工:又称为双向交替通信,即通信的双方都可以发送信息,但不能双方同时发送(当然也就不能同时接受)。 全双工:又称为双向同时通信,即通信的双方可以同时发送和接受信息。 备注:单工只要一条信道,而半双工和全双工需都需要两条信道(每个方向各一条)。 9. 网络通信过程 10. 简述一下停等协议 由于IP层是不可靠的,因此TCP需要采取措施使得传输层之间的通信变得可靠。停止等待协议就是保证可靠传输,以流量控制为目的的一个协议。其工作原理简单的说就是每发送一个分组就停止发送,等待对方的确认,在收到确认后再发送下一个分组,如果接受方不返回应答
  • 在pppd处于活动状态时将AT命令发送到SIM900(Sending AT commands to SIM900 whilst pppd is active)
    问题 我有一个连接有SIM900 GSM附加板的Raspberry Pi。 通过遵循本指南,我已成功建立了与pppd的GPRS连接。 (用于不同的GSM模块,但步骤相同) 我想定期向SIM900发送一条AT命令( AT+CCLK? )以检查时钟。 我已经使用screen管理过发送临时AT命令,但是当pppd启动时,我无法使用screen连接到串行线。 它只是直接退出说[screen is terminating] 。 我猜这是因为pppd使用它来连接到互联网。 问:如何在不关闭pppd的情况下获得时钟时间? 查看用户手册的一部分,它说SIM900具有一个按照GSM0710标准设计的多路复用器。 这有用吗? 如果是这样,我将如何实现? 回答1 我将回答这个问题,因为它可能也会对其他人有所帮助。 但是,我想从分享UART接口多路复用的经验开始。 在我完成所有设置之后,一切似乎都运行良好。 但是,当我尝试连接到VPN或传输某些文件时,Raspbian完全冻结了。 我不确定到底是什么问题,但它似乎与n_gsm或cmux组件有关。 但是,像ping,telnet或SSH这样的低带宽应用程序似乎可以正常工作。 n_gsm模块被标记为实验性的,可能不应该在生产中使用。 Raspbian默认不包含n_gsm内核模块。 要开始使用CMUX驱动程序,我们需要更新Raspbian并下载内核源文件
  • NAT详解及相关命令
    NAT详解及相关命令 一、NAT私有网络地址和公有网络地址NAT工作原理NAT功能 二、NAT的相关命令静态NAT动态NAT 三、PAT端口多路复用PAT有以下作用PAT的类型 四、NAPT五、EasyIp六、NAT Server 一、NAT NAT(Network Address Translation)又称为网络地址转换,用于实现私有网络和公有网络之间的互访。 私有网络地址和公有网络地址 1、公有网络地址(以下简称公网地址)是指在互联网上全球唯一的IP地址。2019年11月26日,是人类互联网时代值得纪念的一天,全球近43亿个IPV4地址已经正式耗尽。 2、私有网络地址(以下简称私网地址)是指内部网络或主机的IP地址, IANA (互联网数字分配机构)规定将下列的IP地址保留用作私网地址,不在Internet上被分配,可在一个单位或公司内部使用。RFC1918中规定私有地址如下: A类私有地址: 10.0.0.0~10.255.255.255 B类私有地址: 172.16.0.0~172.31.255.255 C类私有地址: 192.168.0.0~192.168.255.255 NAT工作原理 ——NAT用来将内网地址和端口号转换成合法的公网地址和端口号,建立一个会话,与公网主机进行通信。 ——NAT外部的主机无法主动跟位于NAT内部的主机通信,,NAT内部主机想要通信
  • 浅谈Netty和Python中的事件驱动
    如果把Netty比作一台工厂车间, 那么IO线程就是车间里面的运作机器, IO线程一直在无限循环地做着三件事 1.轮询IO事件 2.处理IO事件 3.执行task任务 无限循环源码位置: io.netty.channel.nio.NioEventLoop#run select()方法源码位置: io.netty.channel.nio.NioEventLoop#select 在Netty中轮询IO事件是通过调用select()方法, 至于底层基于select,poll,epoll哪一种, 这个和平台有关.总之, 通过select()方法, 监听着ACCEPT,CONNECT,READ,WRITE等事件.一旦有相应的事件发生, Netty就会根据不同的事件调用不同的方法. 处理不同事件的源码位置: io.netty.channel.nio.NioEventLoop#processSelectedKey(java.nio.channels.SelectionKey, io.netty.channel.nio.AbstractNioChannel) CONNECT事件. 在前面的文章谈及过, Netty客户端在向服务端发起连接的时候, 并不会阻塞, 而是直接返回, 然后会注册一个CONNECT事件. 当三次握手完成之后, Netty客户端监听到CONNECT事件
  • 浅谈Netty和Python中的事件驱动
    如果把Netty比作一台工厂车间, 那么IO线程就是车间里面的运作机器, IO线程一直在无限循环地做着三件事 1.轮询IO事件 2.处理IO事件 3.执行task任务 无限循环源码位置: io.netty.channel.nio.NioEventLoop#run select()方法源码位置: io.netty.channel.nio.NioEventLoop#select 在Netty中轮询IO事件是通过调用select()方法, 至于底层基于select,poll,epoll哪一种, 这个和平台有关.总之, 通过select()方法, 监听着ACCEPT,CONNECT,READ,WRITE等事件.一旦有相应的事件发生, Netty就会根据不同的事件调用不同的方法. 处理不同事件的源码位置: io.netty.channel.nio.NioEventLoop#processSelectedKey(java.nio.channels.SelectionKey, io.netty.channel.nio.AbstractNioChannel) CONNECT事件. 在前面的文章谈及过, Netty客户端在向服务端发起连接的时候, 并不会阻塞, 而是直接返回, 然后会注册一个CONNECT事件. 当三次握手完成之后, Netty客户端监听到CONNECT事件
  • 浅谈Netty和Python中的事件驱动
    如果把Netty比作一台工厂车间, 那么IO线程就是车间里面的运作机器, IO线程一直在无限循环地做着三件事 1.轮询IO事件 2.处理IO事件 3.执行task任务 无限循环源码位置: io.netty.channel.nio.NioEventLoop#run > select()方法源码位置: io.netty.channel.nio.NioEventLoop#select 在Netty中轮询IO事件是通过调用select()方法, 至于底层基于select,poll,epoll哪一种, 这个和平台有关.总之, 通过select()方法, 监听着ACCEPT,CONNECT,READ,WRITE等事件.一旦有相应的事件发生, Netty就会根据不同的事件调用不同的方法. 处理不同事件的源码位置: io.netty.channel.nio.NioEventLoop#processSelectedKey(java.nio.channels.SelectionKey, io.netty.channel.nio.AbstractNioChannel) CONNECT事件. 在前面的文章谈及过, Netty客户端在向服务端发起连接的时候, 并不会阻塞, 而是直接返回, 然后会注册一个CONNECT事件. 当三次握手完成之后, Netty客户端监听到CONNECT事件
  • Netty架构基础之BIO NIO AIO网络编程模型
    前言 公司业务需求,需要用到tcp数据传输,基于java自带的socket太low,而且编程复杂,市面上比较流行的netty比较适合。学习netty之前,先简单总结一下各种数据传输类型。 java支持的类型 Java 共支持 3 种网络编程模型/IO 模式:BIO、NIO、AIO Java BIO: 理解: 同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器 端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销 适用场景:BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,但程序简单易理解。 通俗理解:一个请求需要创建一个新的线程,如果客户端比较多的话,服务器肯定是受不了的 Java NIO : 理解: 同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注 册到多路复用器上,多路复用器轮询到连接有 I/O 请求就进行处理 适用场景:NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。 编程比较复杂,JDK1.4 开始支持。 通俗理解:NIO有缓冲池,有通道。有选择器,一个选择器一个线程,多个通道对应多个缓冲池,可对应一个通道,这样有请求过来,直接放到选择器
  • 一文带你看懂多路复用与多路分解
    写在前面:这里是小王成长日志,一名普通在校大学生,想成学习之余将自己的学习笔记分享出来,记录自己的成长轨迹,帮助可能需要的人,平时博客内容主要是一些系统的学习笔记,项目实战笔记,一些技术的探究和自己的一些思考。欢迎大家关注,你们的每一个评论点赞关注我都会仔仔细细去看的。有任何问题欢迎交流,我会尽我所能帮助大家的,共创CSDN美好环境。 最近在看计算机网络,这算是学习笔记吧,因为是自学,水平有限,不一定很有深度,但保证发出来的东西一定是自己思考整理过后的,每句话都经过了查证,欢迎大佬指导,若有错,请轻喷。 文章目录 前置知识进程如何取得来自网络的数据运输层报文结构 概述多路分解多路复用举个栗子 UDP和TCP中的多路复用和多路分解有何不同UDP套接字-无连接的多路分解与多路复用TCP套接字-面向连接的多路复用与多路分解Web服务器与TCP 前置知识 进程如何取得来自网络的数据 首先我们了解进程从网络中接收数据的过程: 在目的主机,运输层需要从其下层的网络层接收报文段。 而运输层则负责将这些报文段中的数据交付给目标进程的指定套接字(而一个进程可能有多个套接字) 因此套接字(Socket)充当从进程向网络传递数据和从进程向网络传递数据的门户。 如下图 运输层报文结构 如上我们可见 每个运输层报文中都有两个首部字段-源端口号和目的端口号。 而在主机上,每个套接字都对应着一个进程