2009-11-26 223 views
9

我正在尋找可以代理我的udp數據包的解決方案。我有一個客戶端發送udp數據包到服務器。它們之間的連接非常糟糕,我得到了很多丟包。一種解決方案是有一個新的代理服務器,它只是將所有數據包從客戶端重定向到目標服務器。新的代理服務器與兩個位置都有良好的連接。簡單的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] ' 

我用這兩個腳本來測試它。

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 2012-02-15 18:29:36

2

這個版本發送一個答覆回來。僅適用於一個客戶端。

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

我也爲此寫了一段Python腳本。這一個是雙向的:

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

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

然後,將您的UDP應用程序localhost:localPort和所有的數據包將反彈至remoteHost:remotePort

remoteHost:remotePort發送回來的所有數據包將被退回到應用程序,假設它正在監聽剛剛發送數據包的端口。

+2

我試着點擊upvote幾次,但我只能給一個。感謝你! – kR105 2015-03-21 01:49:10

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); 
       } 
      } 

     } 
    } 
} 
相關問題