I am trying to develop server/client Asynchronous sockets using c#. I have followed guide on MSDN Link. In my case, socket server listening on particular endpoint, many clients can connect to server at a time, clients can talk to server and server can talk to clients. lets say client 1 and client 2 connected with server, client 1 can send message to server and server can send to client 1, same for client 2 case. Now i want clients should be able to communicate with each other through server. For example;client 2 want to communicate with client 1, for that client 2 will send message to server (this message will contain some preset characters;), then server will receive text from client 2 and will get the handler for client 1 and send this message to client 1, client 1 will response the server, Now i want to send the response of client 1 against that message to client 2, but i do not know how to do that because client 1 communicates through its own handler with server, I am struck here, help will be highly appreciated!! my code is given below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
public int clientNumber;
}
public class AsyncSocketServer
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
public static Dictionary<int, StateObject> Clients = new Dictionary<int, StateObject>();
public static int connectedClient = 0;
public AsyncSocketServer()
{
}
public static void startListening() {
Byte[] bytes = new Byte[1024];
int Port = 1122;
IPAddress IP = IPAddress.Parse("127.0.0.1");
IPEndPoint EP = new IPEndPoint(IP, Port);
Socket listner = new Socket(IP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listner.Bind(EP);
listner.Listen(100);
while (true)
{
allDone.Reset();
Console.WriteLine("Waiting for the Connection......");
listner.BeginAccept(new AsyncCallback(AcceptCallBack), listner);
allDone.WaitOne();
}
}
catch(Exception e)
{
Console.WriteLine("Exception Occured ! in start listening method "+e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallBack(IAsyncResult ar)
{
connectedClient++;
Console.WriteLine("client number " + connectedClient);
allDone.Set();
Socket listner = (Socket) ar.AsyncState;
Socket handler = listner.EndAccept(ar);
StateObject state = new StateObject();
state.clientNumber = connectedClient;
Clients.Add(connectedClient, state);
Console.WriteLine("total clients {0}",Clients.Count());
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;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
try {
StateObject state = (StateObject) ar.AsyncState;
state.sb.Clear();
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.Substring(0, 3) == "cmd") {
foreach (StateObject Client in Clients.Values) {
if (Client.clientNumber == 1) {
Console.WriteLine("value is "+Client.clientNumber);
if (isClientConnected(Client.workSocket)){
Send(Client.workSocket, "did you receive my message");
//now client number 1 will response through its own handler, but i want to get response of
//client number 1 and return this response to client number 2
}
else {
string responsemsg = "client number " + Client.clientNumber + " is disconnected !";
Console.WriteLine(responsemsg);
Send(handler,responsemsg);
}
}
}
}
Console.WriteLine("Read {0} bytes from client {1} socket. \n Data : {2}",
content.Length, state.clientNumber,content);
// Echo the data back to the client.
if (isClientConnected(handler))
{
Send(handler, content);
}
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallBack), state);
}
}
catch (SocketException e)
{
//once if any client disconnected then control will come into this block
Console.WriteLine("Socket Exception Occured in Read Call Back : " + e.Message.ToString());
}
catch (Exception e)
{
//once if any client disconnected then control will come into this block
Console.WriteLine("Exception Occured in Read Call Back : " + e.Message.ToString());
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
//handler.Shutdown(SocketShutdown.Both);
//handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static bool isClientConnected(Socket handler){
return handler.Connected;
}
public static int Main(string[] args)
{
startListening();
return 0;
}
}
}