2009-11-26 13 views
9

Estoy buscando una solución que pueda proxy mis paquetes udp. Tengo un cliente que envía paquetes udp a un servidor. La conexión entre ellos es muy mala y tengo mucha pérdida de paquetes. Una solución es tener un nuevo servidor proxy que redirigirá todos los paquetes desde el cliente al servidor de destino. El nuevo servidor proxy tiene buena conexión a ambas ubicaciones.solución udp proxy simple

Hasta aquí he encontrado simple UDP proxy/pipe

¿Hay algunas herramientas para tal fin?

Saludos

Respuesta

3

Aquí está el código Python escrito para este propósito:

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

He utilizado este dos guiones para probarlo.

import socket 

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

y

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

este script sólo sustitutos en una dirección. – mcr

2

Esta versión envía una respuesta de vuelta. Es bueno para un solo cliente.

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

También escribí un script de Python para este día. Éste va en ambos sentidos:

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

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

A continuación, apuntar su aplicación UDP para localhost:localPort y todos los paquetes se recuperará a remoteHost:remotePort.

Todos los paquetes devueltos desde remoteHost:remotePort se devolverán a la aplicación, suponiendo que esté escuchando en el puerto del que acaba de enviar los paquetes.

+2

Traté de hacer clic varias veces en el voto explícito, pero solo pude dar uno. ¡Gracias por esto! – kR105

1

Aquí es una TCP de trabajo o UDP redirector/UDP Proxy/UDP Tubería/proxy TCP/Pipe TCP


he creado muchos modelos diferentes de gorilas de conexión UDP Proxy y todos ellos parecen perder la conexión con el clase de Sockets estándar, pero usando clases UDPClient este problema desapareció por completo.

El Proxy UDP es sólo 25 líneas de código, pero el poder y la estabilidad está por las nubes

A continuación se presenta ejemplos de cómo hacerlo en TCP y 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); 
       } 
      } 

     } 
    } 
}