Исправлено, вот решение, если кто-то захочет узнать, как я это исправил. Обратите внимание, что это, вероятно, единственный прокси-сервер UDP на всех страницах Google, если вы наткнулись на это .. который написан на C # .. легко портируется на VB.NET с онлайн конвертером .NET
Будь счастлив, этот код работает;)
Конечно, это не эффективно, потому что не использует события .. как ReceiveAsync / EndReceive.
Единственный недостаток в том, чтобы не использовать события Aysnchronize ... это то, что вы видите под рабочим кодом ... придется застревать в бесконечном цикле ... и это сожжет ваши циклы ЦП ... легко исправить с помощью Thread.Sleep ( 10) .. (не устанавливайте высокий уровень, иначе у вас будет задержка с использованием udp)
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace UdpProxy
{
class Program
{
public static IPEndPoint m_listenEp = null;
public static EndPoint m_connectedClientEp = null;
public static IPEndPoint m_sendEp = null;
public static Socket m_UdpListenSocket = null;
public static Socket m_UdpSendSocket = null;
static void Main(string[] args)
{
// Creates Listener UDP Server
m_listenEp = new IPEndPoint(IPAddress.Any, 7900);
m_UdpListenSocket = new Socket(m_listenEp.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
m_UdpListenSocket.Bind(m_listenEp);
//Connect to zone IP EndPoint
m_sendEp = new System.Net.IPEndPoint(IPAddress.Parse("REMOTE_IP_GOES_HERE"), 7900);
m_connectedClientEp = new System.Net.IPEndPoint(IPAddress.Any, 7900);
byte[] data = new byte[1024];
while (true)
{
if (m_UdpListenSocket.Available > 0)
{
int size = m_UdpListenSocket.ReceiveFrom(data, ref m_connectedClientEp); //client to listener
if (m_UdpSendSocket == null)
{
// Connect to UDP Game Server.
m_UdpSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
m_UdpSendSocket.SendTo(data, size, SocketFlags.None, m_sendEp); //listener to server.
}
if (m_UdpSendSocket != null && m_UdpSendSocket.Available > 0)
{
int size = m_UdpSendSocket.Receive(data); //server to client.
m_UdpListenSocket.SendTo(data, size, SocketFlags.None, m_connectedClientEp); //listner
}
}
// Wait for any key to terminate application
Console.ReadKey();
}
}
}
Я всегда оглядываюсь на этот ответ, когда начинаю новый проект UDP Proxy, и у приведенного выше кода есть проблемы с определенными UDP-серверами, на которых он теряет соединения (по протоколу без установления соединения). Да, я понятия не имею, как это происходит. но я исправил это с использованием UDPClient вместо сокетов
Вот другой вариант
Перенаправитель TCP или UDP / UDP-прокси / UDP-канал / TCP-прокси / TCP-канал
Я создал много разных моделей отказов-посредников UDP-прокси, и все они, кажется, теряют соединение, используя стандартный класс Sockets, но с использованием классов UDPClient эта проблема полностью исчезла.
UDP-прокси содержит всего 25 строк кода, но мощность и стабильность не соответствуют графику
Ниже приведены примеры, как сделать это как в TCP, так и в UDP
C # Код ниже
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);
}
}
}
}
}
VB.NET Код ниже
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Net.Sockets
Imports System.Diagnostics
Imports System.Net
Imports System.Threading
Namespace ConsoleApplication1
Class Program
Private Shared Sub Main(args As String())
Dim Address As String = "*PUT IP ADDRESS HERE WHERE UDP SERVER IS*"
Dim UDPPort As Integer = *PUT UDP SERVER PORT HERE*
Dim _UdpRedirect As New UdpRedirect() With { _
Key ._address = Address, _
Key ._Port = UDPPort _
}
Dim _Thread As New Thread(AddressOf _UdpRedirect.Connect)
_Thread.Name = "UDP"
_Thread.Start()
Dim TCPPort As Integer = *PUT TCP SERVER PORT HERE*
Dim _TcpRedirect As New TcpRedirect(Address, TCPPort)
End Sub
End Class
Class UdpRedirect
Public _address As String
Public _Port As Integer
Public Sub New()
End Sub
Public Sub Connect()
Dim _UdpClient As New UdpClient(_Port)
Dim LocalPort As System.Nullable(Of Integer) = Nothing
While True
Dim _IPEndPoint As IPEndPoint = Nothing
Dim _bytes As Byte() = _UdpClient.Receive(_IPEndPoint)
If LocalPort Is Nothing Then
LocalPort = _IPEndPoint.Port
End If
Dim Local As Boolean = IPAddress.IsLoopback(_IPEndPoint.Address)
Dim AddressToSend As String = Nothing
Dim PortToSend As Integer = 0
If Local Then
AddressToSend = _address
PortToSend = _Port
Else
AddressToSend = "127.0.0.1"
PortToSend = LocalPort.Value
End If
_UdpClient.Send(_bytes, _bytes.Length, AddressToSend, PortToSend)
End While
End Sub
End Class
Class TcpRedirect
Public Sub New(_address As String, _Port As Integer)
Dim _TcpListener As New TcpListener(IPAddress.Any, _Port)
_TcpListener.Start()
Dim i As Integer = 0
While True
i += 1
Dim _LocalSocket As TcpClient = _TcpListener.AcceptTcpClient()
Dim _NetworkStreamLocal As NetworkStream = _LocalSocket.GetStream()
Dim _RemoteSocket As New TcpClient(_address, _Port)
Dim _NetworkStreamRemote As NetworkStream = _RemoteSocket.GetStream()
Console.WriteLine(vbLf & "<<<<<<<<<connected>>>>>>>>>>>>>")
Dim _RemoteClient As New Client("remote" + i) With { _
Key ._SendingNetworkStream = _NetworkStreamLocal, _
Key ._ListenNetworkStream = _NetworkStreamRemote, _
Key ._ListenSocket = _RemoteSocket _
}
Dim _LocalClient As New Client("local" + i) With { _
Key ._SendingNetworkStream = _NetworkStreamRemote, _
Key ._ListenNetworkStream = _NetworkStreamLocal, _
Key ._ListenSocket = _LocalSocket _
}
End While
End Sub
Public Class Client
Public _ListenSocket As TcpClient
Public _SendingNetworkStream As NetworkStream
Public _ListenNetworkStream As NetworkStream
Private _Thread As Thread
Public Sub New(Name As String)
_Thread = New Thread(New ThreadStart(AddressOf ThreadStartHander))
_Thread.Name = Name
_Thread.Start()
End Sub
Public Sub ThreadStartHander()
Dim data As [Byte]() = New Byte(99998) {}
While True
If _ListenSocket.Available > 0 Then
Dim _bytesReaded As Integer = _ListenNetworkStream.Read(data, 0, _ListenSocket.Available)
_SendingNetworkStream.Write(data, 0, _bytesReaded)
Console.WriteLine("(((((((" + _bytesReaded + "))))))))))" + _Thread.Name + vbLf + ASCIIEncoding.ASCII.GetString(data, 0, _bytesReaded).Replace(CChar(7), "?"C))
End If
Thread.Sleep(10)
End While
End Sub
End Class
End Class
End Namespace