Created
August 20, 2019 10:19
-
-
Save c6burns/70cc7a51e33d0a27b699de939aa98a09 to your computer and use it in GitHub Desktop.
threaded nonblocking send / recv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Diagnostics; | |
namespace UDPClientPlayground | |
{ | |
class Program | |
{ | |
const string remoteIP = "127.0.0.1"; | |
const int bindPort = 9050; | |
const int recvTimeout = 500; | |
public static volatile bool ceaseRecv, ceaseSend; | |
static Thread recvThread, sendThread; | |
static UdpClient udpClient; | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("UDP Test application"); | |
recvThread = new Thread(RecvThread); | |
recvThread.Start(); | |
sendThread = new Thread(SendThread); | |
sendThread.Start(); | |
Console.ReadKey(); | |
ceaseRecv = true; | |
ceaseSend = true; | |
recvThread.Join(); | |
sendThread.Join(); | |
Console.WriteLine("Application quit"); | |
} | |
static void RecvThread() | |
{ | |
using (udpClient = new UdpClient(bindPort, AddressFamily.InterNetwork)) | |
{ | |
udpClient.Client.Blocking = false; | |
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 9050); | |
byte[] recvData = null; | |
while (!ceaseRecv) | |
{ | |
int recvBytes = UdpClientTryRecv(udpClient, ref recvData, ref ep, recvTimeout); | |
if (recvBytes < 0) | |
{ | |
break; | |
} | |
if (recvBytes > 0) | |
{ | |
Console.WriteLine("Recv: {0} bytes", recvBytes); | |
} | |
} | |
} | |
} | |
static void SendThread() | |
{ | |
using (udpClient = new UdpClient(AddressFamily.InterNetwork)) | |
{ | |
udpClient.Client.Blocking = false; | |
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(remoteIP), bindPort); | |
byte[] sendData = new byte[256]; | |
while (!ceaseRecv) | |
{ | |
int sendBytes = UdpClientTrySend(udpClient, ref sendData, ep, recvTimeout); | |
if (sendBytes < 0) | |
{ | |
break; | |
} | |
if (sendBytes > 0) | |
{ | |
Console.WriteLine("Send: {0} bytes", sendBytes); | |
} | |
} | |
} | |
} | |
static int UdpClientTryRecv(UdpClient udpClient, ref byte[] data, ref IPEndPoint ep, int timeoutMS = 0) | |
{ | |
Stopwatch sw = Stopwatch.StartNew(); | |
do | |
{ | |
try | |
{ | |
data = udpClient.Receive(ref ep); | |
if (data != null) return data.Length; | |
} | |
catch (SocketException ex) | |
{ | |
if (ex.SocketErrorCode != SocketError.WouldBlock) | |
{ | |
Console.WriteLine("Except occurred during recv: {0}", ex.Message); | |
return -1; | |
} | |
} | |
} while (sw.ElapsedMilliseconds < timeoutMS); | |
return 0; | |
} | |
static int UdpClientTrySend(UdpClient udpClient, ref byte[] data, IPEndPoint ep, int timeoutMS = 0) | |
{ | |
Stopwatch sw = Stopwatch.StartNew(); | |
do | |
{ | |
try | |
{ | |
return udpClient.Send(data, data.Length, ep); | |
} | |
catch (SocketException ex) | |
{ | |
if (ex.SocketErrorCode != SocketError.WouldBlock) | |
{ | |
Console.WriteLine("Except occurred during send: {0}", ex.Message); | |
return -1; | |
} | |
} | |
} while (sw.ElapsedMilliseconds < timeoutMS); | |
return 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment