2009-11-26 8 views
9

Tôi đang tìm giải pháp có thể ủy quyền gói udp của tôi. Tôi có một khách hàng gửi gói tin udp đến một máy chủ. Kết nối giữa chúng là rất xấu và tôi nhận được rất nhiều mất gói. Một giải pháp là có một máy chủ proxy mới sẽ chuyển hướng tất cả các gói từ máy khách đến máy chủ đích. Máy chủ proxy mới có kết nối tốt với cả hai vị trí.giải pháp proxy udp đơn giản

Cho đến nay tôi đã tìm thấy đơn giản UDP proxy/pipe

Có một số công cụ cho mục đích như vậy?

Cheers

Trả lời

3

Đây là mã Python bằng văn bản cho mục đích này:

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

Tôi sử dụng này hai kịch bản để kiểm tra nó.

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

Kịch bản này proxy trong một phương hướng. – mcr

2

Phiên bản này sẽ gửi một bài trả lời lại. Nó chỉ tốt cho một khách hàng.

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

Tôi cũng đã viết một tập lệnh Python cho một ngày này. Cái này đi cả hai cách:

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

Cách sử dụng: udp-relay.py localPort:remoteHost:remotePort

Sau đó, chỉ áp dụng UDP của bạn để localhost:localPort và tất cả các gói sẽ bị trả để remoteHost:remotePort.

Tất cả các gói được gửi lại từ remoteHost:remotePort sẽ bị trả về ứng dụng, giả sử nó đang nghe trên cổng mà nó vừa gửi gói từ đó.

+2

Tôi đã cố gắng nhấp vào số lần tải lên nhiều lần nhưng tôi chỉ có thể cho một lần duy nhất. Cám ơn vì cái này! – kR105

1

Đây là một TCP làm việc hoặc UDP Redirector/UDP Proxy/UDP ống/TCP Proxy/TCP Ống


Tôi tạo ra nhiều mô hình khác nhau của bouncers kết nối UDP Proxy và tất cả dường như bị mất kết nối bằng cách sử dụng lớp Sockets chuẩn, nhưng sử dụng các lớp UDPClient vấn đề này hoàn toàn biến mất.

Các UDP Proxy là chỉ có 25 dòng mã nhưng sức mạnh và sự ổn định là tắt các bảng xếp hạng

Dưới đây là ví dụ về làm thế nào để làm điều đó trong cả TCP và UDP chỉ

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

     } 
    } 
}