我有一些客户端同时连接到服务器,并且每个客户端都向服务器发送注册消息。
因此,当消息进入服务器时,消息会与之前的消息冲突。
如何在不消息冲突的情况下管理通信?
我在C#中使用异步tcp套接字。
服务器:
class ServerSocket
{
//The ClientInfo structure holds the required information about every
//client connected to the server
struct ClientInfo
{
public Socket socket; //Socket of the client
public string strName; //Name by which the user logged into the chat room
}
//The collection of all clients logged into the room (an array of type ClientInfo)
ArrayList clientList;
//The main socket on which the server listens to the clients
Socket serverSocket;
byte[] byteData = new byte[5000];
const int NUM_CLIENT = 12;
public ServerSocket()
{
clientList = new ArrayList();
}
public void LoadServer()
{
try
{
//We are using TCP sockets
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Assign the any IP of the machine and listen on port number 1000
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);
//Bind and listen on the given address
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(NUM_CLIENT);
//Accept the incoming clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
Console.WriteLine("###################### S E R V E R ######################");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnAccept(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
//Start listening for more clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
//Once the client connects then start receiving the commands from her
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void OnReceive(IAsyncResult ar)
{
string msgReceived = "";
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);
msgReceived = GetString(byteData);
string strTemp = "";
for (int i = 0; i < msgReceived.IndexOf("<END>"); i++)
{
strTemp += msgReceived[i];
}
msgReceived = strTemp;
XmlBaseClientMsg xmlBaseClientMsg = new XmlBaseClientMsg();
BaseClientMsg baseClientMsgReceived = new BaseClientMsg();
baseClientMsgReceived = xmlBaseClientMsg.DeserializeFromString(msgReceived);
switch (baseClientMsgReceived.m_messageType)
{
case ClientMsgType.AI_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo AIClientInfo = new ClientInfo();
AIClientInfo.socket = clientSocket; // save the socket
AIClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(AIClientInfo);
Console.WriteLine("The client: " + AIClientInfo.strName + " registered");
break;
case ClientMsgType.ENTITY_REGISTRATION:
//When a user logs in to the server then we add him to our list of clients
ClientInfo EntityClientInfo = new ClientInfo();
EntityClientInfo.socket = clientSocket; // save the socket
EntityClientInfo.strName = baseClientMsgReceived.m_sSenderID; // save the name of sender client
clientList.Add(EntityClientInfo);
Console.WriteLine("The client: " + EntityClientInfo.strName + " registered");
break;
#region
//case Command.Logout:
// //When a user wants to log out of the server then we search for her
// //in the list of clients and close the corresponding connection
// int nIndex = 0;
// foreach (ClientInfo client in clientList)
// {
// if (client.socket == clientSocket)
// {
// clientList.RemoveAt(nIndex);
// break;
// }
// ++nIndex;
// }
// clientSocket.Close();
// break;
#endregion
}
if (baseClientMsgReceived.m_messageType != ClientMsgType.AI_REGISTRATION)
{
Console.WriteLine("Type message: " + baseClientMsgReceived.m_messageType + " To: " +
baseClientMsgReceived.m_sReceiverID + " From: " + baseClientMsgReceived.m_sSenderID);
foreach (ClientInfo clientInfo in clientList)
{
if (clientInfo.strName == baseClientMsgReceived.m_sReceiverID)
{
byte[] message;
message = GetBytes(msgReceived);
// Send the message to reciever client
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
Console.WriteLine("Msg No : " + baseClientMsgReceived.m_nMessageID + " Type: " + baseClientMsgReceived.m_messageType + " ==> has been sent");
break;
}
}
}
////If the user disconnects so no need to listen to him
// if (baseClientMsgReceived.m_messageType != ClientMsgType.Logout)
//{
//Start listening to the message send by the user
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
class Program
{
public static int Main( String[] args )
{
ServerSocket serverSocket = new ServerSocket();
serverSocket.LoadServer();
while(true)
{
Console.ReadLine();
}
}
}
}