I have this C# client server application, and I started with the Microsoft documentation
Asynchronous Client Socket Example | Microsoft Docs[
^] . However, I did need to modify some stuff and I would need for client to send multiple messages to server, and also to get multiple back.
Starting from scratch, for example I am in controller (which is in client) and I Send this message to server:
namespace client.ObjectHandler
{
public class BaseHandler
{
private AsynchronousClient asynchronousClient;
public static String username;
public BaseHandler(AsynchronousClient asynchronousClient = null)
{
this.asynchronousClient = asynchronousClient ?? new AsynchronousClient();
}
public User findByUsername(String username)
{
StringBuilder Content = new StringBuilder();
Content.Append("find user ");
Content.Append(username);
Content.Append(" <EOF>");
Message message = new Message { Content = Content.ToString() };
asynchronousClient.Send(message);
asynchronousClient.sendDone.WaitOne();
asynchronousClient.Receive();
asynchronousClient.receiveDone.WaitOne();
var result = asynchronousClient.response;
return result.userContent;
}
}
}
hence the server has to do the operations(in my case accessing the database etc). This is client code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using core;
using System.IO;
namespace client
{
public class AsynchronousClient
{
private const int port = 9000;
public ManualResetEvent connectDone =
new ManualResetEvent(false);
public ManualResetEvent sendDone =
new ManualResetEvent(false);
public ManualResetEvent receiveDone =
new ManualResetEvent(false);
public Message response = new Message();
private Socket client;
private IPHostEntry ipHostInfo;
private IPAddress ipAddress;
private IPEndPoint remoteEP;
public AsynchronousClient()
{
ipHostInfo = Dns.GetHostEntry("localhost");
ipAddress = ipHostInfo.AddressList[0];
remoteEP = new IPEndPoint(ipAddress, port);
client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void Receive()
{
try
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
Message receivedMessage = new Message();
if (bytesRead > 0)
{
receivedMessage = (Message)Serializer.FromStream(new MemoryStream(state.buffer));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
response = receivedMessage;
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void Send(Message message)
{
MemoryStream stream = Serializer.ToStream(message);
byte[] byteData = stream.GetBuffer();
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
private void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
and server code:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using core;
using server;
public class AsynchronousSocketListener
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
private IPHostEntry ipHostInfo;
private IPAddress ipAddress;
private IPEndPoint localEndPoint;
private Socket listener;
public AsynchronousSocketListener()
{
ipHostInfo = Dns.GetHostEntry("localhost");
ipAddress = ipHostInfo.AddressList[0];
localEndPoint = new IPEndPoint(ipAddress, 9000);
listener = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
}
public void StartListening()
{
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
Message receivedMessage = new Message();
if (bytesRead > 0)
{
receivedMessage = (Message)Serializer.FromStream(new MemoryStream(state.buffer));
content = receivedMessage.Content;
if (content.IndexOf("<EOF>") > -1)
{
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
HandleMessage.handle(handler, receivedMessage);
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
else
{
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, Message message)
{
MemoryStream stream = Serializer.ToStream(message);
byte[] byteData = stream.GetBuffer();
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
and the method handle from handleMessage does this:
using System;
namespace server
{
public static class HandleMessage
{
private static BaseHandler baseHandler;
public static void handle(Socket handler, Message message)
{
baseHandler = new BaseHandler();
String[] received = message.Content.Split(' ');
if(received[0].CompareTo("find") == 0)
{
if(received[1].CompareTo("user") == 0)
{
var result = baseHandler.filterByUsername(received[2]);
Message sentMessage = new Message { userContent = result };
MemoryStream stream = Serializer.ToStream(sentMessage);
var bytesSent = handler.Send(stream.GetBuffer());
}
}
}
}
}
What I have tried:
I tried to put in the server after send(handler, message) beginReceive but my code is blocking and I don't find anything helpful