我正在尋找可以代理我的udp數據包的解決方案。我有一個客戶端發送udp數據包到服務器。它們之間的連接非常糟糕,我得到了很多丟包。一種解決方案是有一個新的代理服務器,它只是將所有數據包從客戶端重定向到目標服務器。新的代理服務器與兩個位置都有良好的連接。簡單的udp代理解決方案
到目前爲止,我已經找到簡單UDP proxy/pipe
是否有一些工具,這樣的目的是什麼?
乾杯
我正在尋找可以代理我的udp數據包的解決方案。我有一個客戶端發送udp數據包到服務器。它們之間的連接非常糟糕,我得到了很多丟包。一種解決方案是有一個新的代理服務器,它只是將所有數據包從客戶端重定向到目標服務器。新的代理服務器與兩個位置都有良好的連接。簡單的udp代理解決方案
到目前爲止,我已經找到簡單UDP proxy/pipe
是否有一些工具,這樣的目的是什麼?
乾杯
這裏就是爲了這個目的編寫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()
這個版本發送一個答覆回來。僅適用於一個客戶端。
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] '
我也爲此寫了一段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
發送回來的所有數據包將被退回到應用程序,假設它正在監聽剛剛發送數據包的端口。
我試着點擊upvote幾次,但我只能給一個。感謝你! – kR105 2015-03-21 01:49:10
這裏是一個工作 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);
}
}
}
}
}
此腳本只代理一個方向。 – mcr 2012-02-15 18:29:36