Hello,
I'm writing a Client-Server application using sockets (asynchronous).
There is a Server (Master) which accepts incoming connections, and
Client (Slave).
Afetr establishing connections with all Slaves I wanna hit a button
"Automatic", then everything must be reorganised, there is an
ellection for a new Master.
Everything is all right when I'm connecting manually (when I hit a
button connect), but after hitting this button (Automatic) it looks
like there is to many connections at the same time :/
When a Slave is connecting he's sending a Login command, Master is
responding to him with a unique number for him (his name). It looks
like all of them are sent, but they are not reaching the slaves.
I'm new in C# and I think that I'm doing something wrong. Maybe there
is some special way for mantaining many request at the same time.
Here are the most important fragments of my code:
Form1.cs:
private void btnAutomatic_Click(object sender, EventArgs e)
{
//We're flushing the info about CPU speed's of each
connected slave
//We're sending the Ellection Command to each connected
Slave
Data msgToSend = new Data();
byte[] message;
msgToSend.cmdCommand = Command.Ellection;
message = msgToSend.ToByte();
lock (_master.__clientList)
{
foreach (ClientInfo client in _master.__clientList)
{
if (client.type == 1)
{
client.cpuSpeed = 0;
client.socket.BeginSend(message, 0,
message.Length, SocketFlags.None, new AsyncCallback(_master.OnSend),
client.socket);
}
}
}
}
- Master.cs:
private void OnReceive(IAsyncResult ar)
{
lock (__clientList)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);
//Transform the array of bytes received from the
user into an intelligent form of object Data
Data msgReceived = new Data(byteData);
//We will send this object in response the users
request
Data msgToSend = new Data();
byte[] message;
msgToSend.cmdCommand = msgReceived.cmdCommand;
msgToSend.strName = msgReceived.strName;
mainForm.messageReceived(msgReceived.strName,
Convert.ToString(msgReceived.cmdCommand), msgReceived.strMessage);
switch (msgReceived.cmdCommand)
{
case Command.Login:
//When a user logs in to the server then
we're adding him to our list of clients
ClientInfo clientInfo = new ClientInfo();
clientInfo.socket = clientSocket;
//Set an unique name (number) for every
connected client
if (_clientList.Count == 0)
clientInfo.nr = 0;
else
{
foreach (ClientInfo client in
__clientList)
{
if (clientInfo.nr <=
client.nr)
clientInfo.nr = client.nr
+ 1;
}
}
clientInfo.strName = msgReceived.strName +
clientInfo.nr;
if (msgReceived.strName == "slave")
clientInfo.type = 1;
else
clientInfo.type = 2;
_clientList.Add(clientInfo);
//Set the text of the message which will
be send to user who just logged into our server
msgToSend.strMessage = "Your name is: ";
msgToSend.strName =
clientInfo.nr.ToString();
mainForm.messageReceived(msgToSend.strName,
Convert.ToString(msgToSend.cmdCommand), "He's name is: ");
message = msgToSend.ToByte();
clientInfo.socket.BeginSend(message, 0,
message.Length, SocketFlags.None, new AsyncCallback(OnSend),
clientInfo.socket);
mainForm.newClientConnected(clientInfo.strName);
break;
- Slave.cs:
private void OnReceive(IAsyncResult ar)
{
try
{
clientSocket.EndReceive(ar);
Data msgReceived = new Data(byteData);
Data msgToSend = new Data();
byte[] b;
mainForm.messageReceived(msgReceived.strName,
Convert.ToString(msgReceived.cmdCommand), msgReceived.strMessage);
//Process the message received
switch (msgReceived.cmdCommand)
{
case Command.Login:
nr = Convert.ToInt32(msgReceived.strName);
strName = "slave" + nr.ToString();
mainForm.setTitle(strName);
break;
Thank you very much for all issues and ideas.
P.S. Sorry for my english.
Lukas