I've started learning System.Net, and coded a simple UDP client-server chat application.
The client and server are both located on my machine (via local) for simplicity reasons.
I can send a message from client to server and write it there, but after that, the client should receive a hardcoded message too (Hello again!), which is my problem.
Screenshot of application (server and client)
Client code:
public class UDPClient
{
private Socket clientSocket;
private EndPoint epSend, epRecieve;
private byte[] dataBuffer;
private ArraySegment<byte> dataBufferSegments;
/// <summary>
/// initializing client with buffer, end points of server and client (for sending and listening)
/// </summary>
/// <param name="address"></param>
/// <param name="port">for future port-forwarding</param>
public void Initialize(IPAddress address, int port = 0)
{
dataBuffer = new byte[4096];
dataBufferSegments = new ArraySegment<byte>(dataBuffer);
epRecieve = new IPEndPoint(address, clientListenOn);
epSend = new IPEndPoint(address, serverListenOn);
Console.WriteLine(epRecieve.Serialize());
Console.WriteLine(epSend.Serialize());
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
clientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
}
/// <summary>
/// async task for listening on packets
/// </summary>
public void Listen()
{
_ = Task.Run(async () =>
{
SocketReceiveMessageFromResult res;
while (true)
{
res = await clientSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);
Console.WriteLine(Encoding.UTF8.GetString(dataBuffer, 0, bufferSize));
}
});
}
/// <summary>
/// async task for sending data back to server
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task Send(byte[] data)
{
var s = new ArraySegment<byte>(data);
await clientSocket.SendToAsync(s, SocketFlags.None, epSend);
}
}
Server code:
/// <summary>
/// UDP Server
/// </summary>
public class UDPServer
{
private Socket serverSocket;
private EndPoint epRecieve, epSend;
private byte[] dataBuffer;
private ArraySegment<byte> dataBufferSegments;
public void Initialize()
{
dataBuffer = new byte[4096];
dataBufferSegments = new ArraySegment<byte>(dataBuffer);
epRecieve = new IPEndPoint(IPAddress.Loopback, serverListenOn);
Console.WriteLine(epRecieve.Serialize());
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
serverSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
serverSocket.Bind(epRecieve);
}
public void Listen()
{
_ = Task.Run(async () =>
{
SocketReceiveMessageFromResult res;
while (true)
{
res = await serverSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);
Console.WriteLine(Encoding.UTF8.GetString(dataBuffer, 0, bufferSize));
Console.WriteLine(res.RemoteEndPoint);
Console.WriteLine(res.ReceivedBytes.ConvertToString());
Console.WriteLine(res.PacketInformation.Address);
epSend = new IPEndPoint(res.PacketInformation.Address, clientListenOn);
Console.WriteLine(epSend.Serialize());
//this doesn't seem to work...
await SendTo(epSend, Encoding.UTF8.GetBytes("Hello back!"));
}
});
}
public async Task SendTo(EndPoint recipient, byte[] data)
{
var s = new ArraySegment<byte>(data);
await serverSocket.SendToAsync(s, SocketFlags.None, recipient);
}
}
Server main code:
static void Main(string[] args)
{
Network.UDPServer server = new Network.UDPServer();
server.Initialize();
server.Listen();
Console.ReadLine();
}
Client main code:
static async Task Main(string[] args)
{
Network.UDPClient client = new Network.UDPClient();
IPAddress ip = IPAddress.Loopback;
Console.WriteLine(ip.ToString());
client.Initialize(ip);
client.Listen();
await client.Send(Encoding.UTF8.GetBytes(Console.ReadLine()));
Console.ReadLine();
}
Thus I would like anybody to pinpoint out what's wrong with my system.
Much appreciate!
CodePudding user response:
I pasted your code on Visual Studio and with minor monifications (some missing fields etc), the problem I came across is the following:
On your UDP client, this line throws an exception of type InvalidOperationException
.
System.InvalidOperationException: 'You must call the Bind method before performing this operation.'
res = await clientSocket.ReceiveMessageFromAsync(dataBufferSegments, SocketFlags.None, epRecieve);
You need to bind the socket to a local endpoint, specifically your receive endpoint. This is done in order to associate that socket with that specific endpoint and receive data from it.
public void Initialize(IPAddress address, int port = 0)
{
dataBuffer = new byte[4096];
dataBufferSegments = new ArraySegment<byte>(dataBuffer);
epRecieve = new IPEndPoint(address, clientListenOn);
epSend = new IPEndPoint(address, serverListenOn);
Console.WriteLine(epRecieve.Serialize());
Console.WriteLine(epSend.Serialize());
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
clientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
_clientSocket.Bind(_epRecieve);
}
You can read more here: MSDN - Socket.Bind(EndPoint) Method