Original Post
Hello, I'm a newb when it comes to System.Net.Sockets but I understand the basics. I'm working on a game that allows multiple clients to connect to a server. I'll try to keep my question as short as possible but it requires some explanation... When a client connects, the server adds the socket to an ArrayList. Then it passes the index of the client (ArrayList.Count - 1) to the WaitForData method. This way the first client that connects has an index of 0, the second has an index of 1, etc. When the server receives data, it creates a state object that stores the socket, the data, and the index of the client that sent the data. When a client disconnects, the server removes the socket from the ArrayList and relays back to all the other clients that someone disconnected. My problem is that the index is stored in a state object rather than a local variable so theres no way to iterate through each client and decrement the index if someone disconnects. For example: 3 clients connect to the server with the indeces 0 1 and 2. If client1 disconnects, client2 should become client1 and client0 should stay the same. What really happens: If client1 disconnects, the other clients still have the index 0 and 2, resulting in a OutOfRangeException. Is there any way I can accomplish this? Any help would be greatly appreciated, thanks. [Edited by - majek on March 20, 2009 4:32:32 PM]
private void ClientConnected(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
SocketList.Add(clientSocket);
onClientConnect(SocketList.Count - 1);
WaitForData(clientSocket, SocketList.Count - 1);
serverSocket.BeginAccept(new AsyncCallback(ClientConnected), null);
}
catch (SocketException se)
MessageBox.Show(se.Message);
}
private void WaitForData(Socket clientSocket, int clientIndex)
{
try
{
if (WaitForDataCallback == null) WaitForDataCallback = new AsyncCallback(DataReceived);
ServerPacket serverPacket = new ServerPacket(clientSocket, clientIndex);
clientSocket.BeginReceive(serverPacket.DataBuffer, 0, serverPacket.DataBuffer.Length, SocketFlags.None, WaitForDataCallback, serverPacket);
}
catch (SocketException se)
MessageBox.Show(se.Message);
}
private void DataReceived(IAsyncResult ar)
{
ServerPacket serverPacket = (ServerPacket)ar.AsyncState;
try
{
int iRx = serverPacket.CurrentSocket.EndReceive(ar);
char[] chars = new char[iRx + 1];
Decoder d = Encoding.UTF8.GetDecoder();
int charLength = d.GetChars(serverPacket.DataBuffer, 0, iRx, chars, 0);
string szData = new string(chars);
onDataReceived(szData, serverPacket.ClientIndex);
WaitForData(serverPacket.CurrentSocket, serverPacket.ClientIndex);
}
catch (SocketException se)
{
if (se.ErrorCode == 10054) // Connection reset by peer
onClientDisconnect(serverPacket.ClientIndex);
else MessageBox.Show(se.Message);
}
}
public class ServerPacket
{
public Socket CurrentSocket;
public int ClientIndex;
public byte[] DataBuffer;
public ServerPacket(Socket currentSocket, int clientIndex)
{
CurrentSocket = currentSocket;
ClientIndex = clientIndex;
DataBuffer = new byte[1024];
}
}