代码之家  ›  专栏  ›  技术社区  ›  Alex

简单的UDP代理解决方案

  •  9
  • Alex  · 技术社区  · 16 年前

    我正在寻找可以代理我的UDP数据包的解决方案。我有一个客户端向服务器发送UDP数据包。它们之间的连接非常糟糕,我经常丢失数据包。一种解决方案是使用一个新的代理服务器,它只将所有数据包从客户机重定向到目标服务器。新的代理服务器与两个位置都有良好的连接。

    到目前为止,我觉得很简单 UDP proxy/pipe

    有没有这样的工具?

    干杯

    4 回复  |  直到 10 年前
        1
  •  17
  •   Etienne Perot    14 年前

    我还为这一天编写了一个python脚本。这是双向的:

    https://github.com/EtiennePerot/misc-scripts/blob/master/udp-relay.py

    用途: udp-relay.py localPort:remoteHost:remotePort

    然后,将您的UDP应用程序指向 localhost:localPort 所有的包都会跳到 remoteHost:remotePort .

    从发送回来的所有数据包 远程主机:远程端口 将被反弹回应用程序,假设它正在监听它刚发送数据包的端口。

        2
  •  3
  •   Alex    16 年前

    下面是为此目的编写的python代码:

    import socket
    from threading import Thread
    
    class Proxy(Thread):
        """ used to proxy single udp connection 
        """
        BUFFER_SIZE = 4096 
        def __init__(self, listening_address, forward_address):
            print " Server started on", listening_address
            Thread.__init__(self)
            self.bind = listening_address
            self.target = forward_address
    
        def run(self):
            # listen for incoming connections:
            target = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            target.connect(self.target)
    
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                s.bind(self.bind)
            except socket.error, err:
                print "Couldn't bind server on %r" % (self.bind, )
                raise SystemExit
            while 1:
                datagram = s.recv(self.BUFFER_SIZE)
                if not datagram:
                    break
                length = len(datagram)
                sent = target.send(datagram)
                if length != sent:
                    print 'cannot send to %r, %r !+ %r' % (self.target, length, sent)
            s.close()
    
    
    if __name__ == "__main__":
        LISTEN = ("0.0.0.0", 8008)
        TARGET = ("localhost", 5084)
        while 1:
            proxy = Proxy(LISTEN, TARGET)
            proxy.start()
            proxy.join()
            print ' [restarting] '
    

    我用这两个脚本来测试它。

    import socket
    
    target = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    target.connect(("localhost", 8008))
    print 'sending:', target.send("test data: 123456789")
    

    import socket
    
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("localhost", 5084))
    while 1:
        datagram = s.recv(1024)
        if not datagram:
            break
        print repr(datagram)
    
    s.close()
    
        3
  •  2
  •   mcr    14 年前

    此版本将返回一个答复。只对一个客户有效。

    import socket
    from threading import Thread
    
    class Proxy(Thread):
        """ used to proxy single udp connection 
        """
        BUFFER_SIZE = 4096 
        def __init__(self, listening_address, forward_address):
            print " Server started on", listening_address
            Thread.__init__(self)
            self.bind = listening_address
            self.target = forward_address
    
        def run(self):
            # listen for incoming connections:
            target = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            target.connect(self.target)
    
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                s.bind(self.bind)
            except socket.error, err:
                print "Couldn't bind server on %r" % (self.bind, )
                raise SystemExit
            while 1:
                (datagram,addr) = s.recvfrom(self.BUFFER_SIZE)
                if not datagram:
                    break
                length = len(datagram)
                sent = target.send(datagram)
                if length != sent:
                    print 'cannot send to %r, %r !+ %r' % (self.s, length, sent)
                datagram = target.recv(self.BUFFER_SIZE)
                if not datagram:
                    break
                length = len(datagram)
                sent = s.sendto(datagram,addr)
                if length != sent:
                    print 'cannot send to %r, %r !+ %r' % (self.s, length, sent)
            s.close()
    
    
    if __name__ == "__main__":
        LISTEN = ("0.0.0.0", 5093)
        TARGET = ("10.12.2.26", 5093)
        while 1:
            proxy = Proxy(LISTEN, TARGET)
            proxy.start()
            proxy.join()
            print ' [restarting] '
    
        4
  •  1
  •   Siyual Ranjit Singh    10 年前

    这是一个工作 TCP或UDP重定向器/UDP代理/UDP管道/TCP代理/TCP管道


    我创建了许多不同的UDP代理连接跳跃器模型,它们似乎都使用标准的sockets类失去了连接,但是使用udpclient类,这个问题完全消失了。

    udp代理只有25行代码,但其功能和稳定性不在图表中。

    下面是如何在TCP和UDP中执行此操作的示例

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Diagnostics;
    using System.Net;
    using System.Threading;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string Address= "*PUT IP ADDRESS HERE WHERE UDP SERVER IS*";
                int UDPPort = *PUT UDP SERVER PORT HERE*;
                UdpRedirect _UdpRedirect = new UdpRedirect() { _address = Address, _Port = UDPPort};
                Thread _Thread = new Thread(_UdpRedirect.Connect);
                _Thread.Name = "UDP";
                _Thread.Start();
    
                int TCPPort = *PUT TCP PORT HERE FOR TCP PROXY*;       
                TcpRedirect _TcpRedirect = new TcpRedirect(Address, TCPPort);            
            }
        }
        class UdpRedirect
        {
            public string _address;
            public int _Port;
            public UdpRedirect()
            {
            }
    
            public void Connect()
            {
                UdpClient _UdpClient = new UdpClient(_Port);
                int? LocalPort = null;
                while (true)
                {
                    IPEndPoint _IPEndPoint = null;
                    byte[] _bytes = _UdpClient.Receive(ref _IPEndPoint);
                    if (LocalPort == null) LocalPort = _IPEndPoint.Port;
                    bool Local = IPAddress.IsLoopback(_IPEndPoint.Address);
                    string AddressToSend = null;
                    int PortToSend = 0;
                    if (Local)
                    {
                        AddressToSend = _address;
                        PortToSend = _Port;
                    }
                    else
                    {
                        AddressToSend = "127.0.0.1";
                        PortToSend = LocalPort.Value;
                    }
                    _UdpClient.Send(_bytes, _bytes.Length, AddressToSend, PortToSend);
                }
            }
        }
        class TcpRedirect
        {
            public TcpRedirect(string _address, int _Port)
            {
    
                TcpListener _TcpListener = new TcpListener(IPAddress.Any, _Port);
                _TcpListener.Start();
                int i = 0;
                while (true)
                {
                    i++;
                    TcpClient _LocalSocket = _TcpListener.AcceptTcpClient();
                    NetworkStream _NetworkStreamLocal = _LocalSocket.GetStream();
    
                    TcpClient _RemoteSocket = new TcpClient(_address, _Port);
                    NetworkStream _NetworkStreamRemote = _RemoteSocket.GetStream();
                    Console.WriteLine("\n<<<<<<<<<connected>>>>>>>>>>>>>");
                    Client _RemoteClient = new Client("remote" + i)
                    {
                        _SendingNetworkStream = _NetworkStreamLocal,
                        _ListenNetworkStream = _NetworkStreamRemote,
                        _ListenSocket = _RemoteSocket
                    };
                    Client _LocalClient = new Client("local" + i)
                    {
                        _SendingNetworkStream = _NetworkStreamRemote,
                        _ListenNetworkStream = _NetworkStreamLocal,
                        _ListenSocket = _LocalSocket
                    };
                }
            }
            public class Client
            {
                public TcpClient _ListenSocket;
                public NetworkStream _SendingNetworkStream;
                public NetworkStream _ListenNetworkStream;
                Thread _Thread;
                public Client(string Name)
                {
                    _Thread = new Thread(new ThreadStart(ThreadStartHander));
                    _Thread.Name = Name;
                    _Thread.Start();
                }
                public void ThreadStartHander()
                {
                    Byte[] data = new byte[99999];
                    while (true)
                    {
                        if (_ListenSocket.Available > 0)
                        {
                            int _bytesReaded = _ListenNetworkStream.Read(data, 0, _ListenSocket.Available);
                            _SendingNetworkStream.Write(data, 0, _bytesReaded);
                            Console.WriteLine("(((((((" + _bytesReaded + "))))))))))" + _Thread.Name + "\n" + ASCIIEncoding.ASCII.GetString(data, 0, _bytesReaded).Replace((char)7, '?'));
                        }
                        Thread.Sleep(10);
                    }
                }
    
            }
        }
    }