I have only done UDP/TCP work using the TcpClient and UdpClient in the past, and never really dove down into barebone sockets programming.
In windows 10, these two libraries are no longer part of System.Net.Sockets, so I figured I’d try to get some help with the following code:
My question is this.
Using UdpClient, getting a response from the device that I want to manage is a breese:
var sendClient = new UdpClient(SEND_PORT);
var remoteIp = IPAddress.Parse(IP_ADDRESS);
var remoteHost = new IPEndPoint(remoteIp, RECEIVE_PORT);
var buffer = new byte[] { 0xff, 0x03, 0x00, 0x00, 0x0E, 0x11, 0xFF };
sendClient.Connect(remoteHost);
sendClient.Send(buffer, 7);
var response = sendClient.Receive(ref remoteHost);
sendClient.Close();
The above code gives me back the data that I am looking for.
Now, fast forward to sockets in Windows 10, and I am confused. I never reach past the initial ProcessSend() method.
I am also noting that there is nowhere where I can enter both the sending port AND the receiving port.
Could someone help me understand these inner workings of Socket programming, and what should I be doing that the UdpClient class masks away from me?
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var remoteIp = IPAddress.Parse(SERVER_IP);
var remoteHost = new IPEndPoint(remoteIp, SERVER_PORT);
// Same bytes in VersionRequest that are on the previous example
var buffer = new byte[7];
Buffer.BlockCopy(Commands.VersionRequest, 0, buffer, 0, 7);
SocketAsyncEventArgs clientArgs = new SocketAsyncEventArgs();
clientArgs.SetBuffer(buffer, 0, 7);
clientArgs.UserToken = socket;
clientArgs.RemoteEndPoint = remoteHost;
clientArgs.Completed += OnOperationComplete;
socket.SendToAsync(clientArgs);
}
private void OnOperationComplete(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError != SocketError.Success)
return;
switch (e.LastOperation)
{
case SocketAsyncOperation.SendTo:
ProcessSend(e);
break;
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.ReceiveFrom:
ProcessReceive(e);
break;
}
}
private void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError != SocketError.Success)
return;
var socket = e.UserToken as Socket;
bool receiveIsPending = socket.ReceiveAsync(e);
if (receiveIsPending)
ProcessReceive(e);
}
private void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.SocketError != SocketError.Success)
throw new SocketException((Int32)e.SocketError);
var message = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
var socket = e.UserToken as Socket;
socket.Shutdown(SocketShutdown.Send);
}