2009-11-26 23 views
9

私はudpパケットをプロキシできるソリューションを探しています。私はサーバーにudpパケットを送信する1つのクライアントがあります。それらの間の接続は非常に悪く、私は多くのパケット損失を受けます。 1つの解決策は、クライアントから宛先サーバーへのすべてのパケットをリダイレクトする新しいプロキシサーバーを用意することです。新しいプロキシサーバーは、両方の場所への接続が良好です。シンプルなudpプロキシソリューション

は、これまでのところ私はUDP proxy/pipe

は、そのような目的のためにいくつかのツールがあります単純な発見しましたか?ここで

乾杯

答えて

3

は、この目的のために書かれた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] ' 

私はそれをテストするには、この2つのスクリプトを使用していました。

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() 
+0

このスクリプトのみプロキシの両方でそれを行う方法の例であるチャートから離れています方向。 – mcr

2

このバージョンでは、バック1つの応答を送信します。それは1つのクライアントのために良いです。

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

私はこの1日のためにPythonスクリプトも書いています。この1は、両方の方法を行く:

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

は使用方法:udp-relay.py localPort:remoteHost:remotePort

その後、localhost:localPortにあなたのUDPアプリケーションを指し、すべてのパケットがremoteHost:remotePortに返送されます。

remoteHost:remotePortから返されたすべてのパケットは、パケットを送信したばかりのポートで待機していると仮定すると、アプリケーションに戻されます。ここで

+2

私はupvoteを何回かクリックしようとしましたが、私は1つしか与えることができませんでした。ありがとう! – kR105

1

作業 TCPやUDPリダイレクタ/ UDPプロキシ/ UDPパイプ/ TCPプロキシ/ TCPパイプ


である私は、UDPプロキシ接続警備員の多くの異なるモデルを作成し、それらはすべて使用して接続を失うように見えます標準のソケットクラスですが、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); 
       } 
      } 

     } 
    } 
} 
関連する問題