سؤال

وأنا أبحث عن الحل الذي يمكن وكيل بلدي حزم UDP. لدي عميل واحد يرسل حزم UDP إلى ملقم. اتصال بينهما هو سيء للغاية وأحصل على الكثير من فقدان الحزمة. حل واحد هو أن يكون هناك ملقم وكيل جديدة من شأنها أن مجرد توجيه كافة الحزم من العميل إلى الملقم الوجهة. الملقم الوكيل الجديد لديه علاقة جيدة لكلا الموقعين.

وحتى الآن لقد وجدت UDP وكيل / الأنابيب

هل هناك بعض الأدوات لهذا الغرض؟

وهتاف

هل كانت مفيدة؟

المحلول 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 = 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()

نصائح أخرى

وكتبت أيضا السيناريو بايثون لهذا اليوم واحدة. هذا واحد يذهب في كلا الاتجاهين:

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