2009-11-26 13 views
9

Szukam rozwiązania, które może proxy moich pakietów udp. Mam jednego klienta wysyłającego pakiety udp na serwer. Połączenie między nimi jest bardzo złe i mam dużo utraty pakietów. Jednym z rozwiązań jest posiadanie nowego serwera proxy, który po prostu przekieruje wszystkie pakiety z klienta na serwer docelowy. Nowy serwer proxy ma dobre połączenie z obiema lokalizacjami.proste rozwiązanie proxy udp

tej pory znalazłem Proste UDP proxy/pipe

Czy istnieją jakieś narzędzia do tego celu?

Cheers

Odpowiedz

3

Oto kod Python napisany w tym celu:

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

użyłem tych dwóch skryptów, aby go przetestować.

import socket 

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

i

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

ten skrypt tylko serwery proxy w jednym kierunek. – mcr

2

Ta wersja wysyła jedną odpowiedź z powrotem. Jest to dobre tylko dla jednego klienta.

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

Napisałem też skrypt w języku Python na ten jeden dzień. To idzie w obie strony:

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

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

Następnie wskaż aplikację UDP localhost:localPort i wszystkie pakiety będą odbijać się remoteHost:remotePort.

Wszystkie pakiety odesłane z remoteHost:remotePort zostaną odesłane z powrotem do aplikacji, zakładając, że nasłuchują na porcie, z którego właśnie wysłali pakiety.

+2

Próbowałem kilkakrotnie kliknąć uptoote, ale mogłem dać tylko jeden. Dzięki za to! – kR105

1

Oto pracuje TCP lub UDP Redirector/UDP Proxy/UDP rur/TCP Proxy/TCP rur


Stworzyłem wiele różnych modeli z bramkarzy połączenia UDP Proxy i wszystkie one wydają się tracić połączenie za pomocą standardowej klasy gniazd, ale przy użyciu klas UDPClient ten problem całkowicie zniknął.

UDP Proxy jest tylko 25 linii kodu, ale moc i stabilność jest wyłączony wykresy

Poniżej przykłady jak to zrobić zarówno TCP i 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); 
       } 
      } 

     } 
    } 
}