سؤال
وأنا أبحث عن الحل الذي يمكن وكيل بلدي حزم 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);
}
}
}
}
}