simple udp proxy solution

前端 未结 4 1389
温柔的废话
温柔的废话 2021-02-04 07:47

I am looking for solution that can proxy my udp packets. I have one client sending udp packets to a server. Connection between them is very bad and I get lot of packet loss. One

相关标签:
4条回答
  • 2021-02-04 08:12

    This version sends one reply back. It's good for one client only.

    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] '
    
    0 讨论(0)
  • 2021-02-04 08:19

    Here is Python code written for this purpose:

    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] '
    

    I used this two scripts to test it.

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

    and

    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()
    
    0 讨论(0)
  • 2021-02-04 08:19

    Here is a working TCP or UDP Redirector / UDP Proxy / UDP Pipe / TCP Proxy / TCP Pipe


    I created many different models of UDP Proxy connection bouncers and they all seem to lose connection using the standard Sockets class, but using UDPClient classes this problem completely went away.

    The UDP Proxy is only 25 lines of code but the power and stability is off the charts

    Below is examples how to do it in both TCP and 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);
                    }
                }
    
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-04 08:35

    I also wrote a Python script for this one day. This one goes both ways:

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

    Usage: udp-relay.py localPort:remoteHost:remotePort

    Then, point your UDP application to localhost:localPort and all packets will bounce to remoteHost:remotePort.

    All packets sent back from remoteHost:remotePort will be bounced back to the application, assuming it is listening on the port it just sent packets from.

    0 讨论(0)
提交回复
热议问题