我正在寻找可以代理我的udp数据包的解决方案。我有一个客户端将udp数据包发送到服务器。它们之间的连接非常糟糕,我丢失了很多数据包。一种解决方案是拥有一个新的代理服务器,它只会将所有数据包从客户端重定向到目标服务器。新的代理服务器与两个位置都有良好的连接。

到目前为止,我找到了简单的 UDP代理/管

是否有一些工具用于此目的?

干杯

有帮助吗?

解决方案 2

以下是为此目的编写的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()

其他提示

我有一天也写了一个Python脚本。这个有两个方面:

https://github.com/EtiennePerot/misc-脚本/斑点/主/ udp-relay.py

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

然后,将您的UDP应用程序指向 localhost:localPort ,所有数据包将跳转到 remoteHost:remotePort

remoteHost:remotePort 发回的所有数据包都将被退回到应用程序,假设它正在侦听它刚才发送数据包的端口。

此版本发回一个回复。这对一个客户来说只是好事。

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

这是一个工作 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);
                }
            }

        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top