473,396 Members | 1,671 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Client-Server application (based on sockets) - too many messages at the same time

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

Jun 1 '07 #1
5 2753
On Fri, 01 Jun 2007 15:13:59 -0700, Cichy <ci*****@gmail.comwrote:
[...]
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.
#1 problem I see in your code is that you don't do anything to check the
number of bytes sent *or* received to ensure that you have a full
"message". Because you write about "connections" I am assuming that you
are using a connection-oriented protocol. That is, TCP. TCP does not
guarantee anything except that the bytes that are received are exactly in
the same order in which they were sent. They may be grouped in entirely
arbitrary ways; you can receive a single byte at a time, or (as is more
common, especially when dealing with "messages" that are relatively small)
you can receive more bytes at once than were sent at once (that is,
multiple sends are combined into a single receive).

That's the receiving side of things, and is the most common error.
However, the same issue exists with respect to sending. You need to check
the count of bytes returned when the send completes to find out how many
bytes *actually* were sent. If fewer bytes were sent than the number you
tried to send, you need to reattempt the send, starting with the first
byte that *wasn't* sent (so index into the original buffer you tried to
send by the number of bytes that were sent, and send the rest of the data
from that point).

Other than that, I don't see anything glaringly wrong with the code you
posted, so I think there's a good chance that a) you are capable of fixing
the above problems without too much trouble (not everyone ought to be
writing networking code, but I'm not hearing alarm bells seeing your code
:) ) and b) that when you do fix those problems, you'll find that your
communications are every bit as reliable as you might hope. :)

If it turns out that you are using UDP, then you have a different problem:
first, UDP doesn't have the concept of "connections" (even though you can
"connect" a UDP socket, that's really just a shorthand way of specifying
the default remote endpoint) and second, UDP isn't reliable (datagrams
sent may go unreceived, they may arrive more than once, and they may
arrive out of order).

Hope that helps.

Pete
Jun 2 '07 #2
Thank you for response Pete.

Yes, You we're right that I'm using TCP Protocol. I thought that when
I'm sending some datas over a socket it's checking how many bytes
we're sent and received.
I really was sure that there is some sort of byte (like EOM - End Of
Message, like EOF in files) which idnicates if everything was sent.

But know I'm not too sure where should I check this things?
When sending it looks more simple, I have a method:

public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
if (eerrorOccured != null)
eerrorOccured(this, ex.Message);
}
}

and probably here i can check how many bytes where sent (probably I
have to add second parameter with message to be able to resend some
bytes).
But where should I check if i received all bytes (and the more
important questions, how could I know how many of them should
be ???).
And also, is this construction doesn't fix the problem of receiving
only a part of a message:

clientSocket.EndReceive(ar);
Thank you for very much your help.
Best wishes,

Lukas

Jun 2 '07 #3
Ohh, and also I forgot to mention that sometimes my application
behaves in a strange way.
When I hit the "Automatic" button I'm receiving an error saying:

"demand of sending or receiving data was blocked, because socket is
not connected (and during sending over a socket datas when using "send
to" there is no address given"

And when I hit OK the message is delivered to this specific Slave.
(???) (He receives a message with his unique number given to him by
Master).

I really don't know why sometimes it behaves fine (altough there is a
exception like above) and usually there is no problem like that, but
no messages a delivered.
Thanks.
Lukas

Jun 2 '07 #4
On Sat, 02 Jun 2007 03:22:52 -0700, Cichy <ci*****@gmail.comwrote:
Yes, You we're right that I'm using TCP Protocol. I thought that when
I'm sending some datas over a socket it's checking how many bytes
we're sent and received.
Define "checking". In one sense, I suppose it is...after all, assuming
nothing's wrong with the connection, the bytes all do eventually get sent
and received. The "how many" is "checked" in that sense.

However, TCP doesn't do anything to ensure that between the first byte
sent and the last byte sent, that everything received is grouped exactly
the same way that it was sent.
I really was sure that there is some sort of byte (like EOM - End Of
Message, like EOF in files) which idnicates if everything was sent.
There's definitely nothing like that. You put a byte in at one end, that
byte comes out at the other. Nothing more, nothing less.
But know I'm not too sure where should I check this things?
You need to look at the return value for Socket.EndReceive() and
Socket.EndSend(). These are integers that tell you how many bytes were
actually successfully received or sent.
When sending it looks more simple, I have a method:

public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
if (eerrorOccured != null)
eerrorOccured(this, ex.Message);
}
}

and probably here i can check how many bytes where sent (probably I
have to add second parameter with message to be able to resend some
bytes).
You need to hang on to the original send buffer, presumably in some
per-client data structure. Along with that, you need to keep track of how
many bytes in the buffer have already been sent, so that when you call
Socket.EndSend(), you can compare the byte count with how many you had
left to send, and if the sent bytes are fewer than the amount you actually
have to send, make another attempt to send the remaining bytes.
But where should I check if i received all bytes (and the more
important questions, how could I know how many of them should
be ???).
Yes, that is the more important question. Your protocol needs to definea
way for the recipient of the data to know how large that data is, so that
it can tell whether it's received it all or not. How this is done depends
entirely on the protocol.

Some precede the data with a byte count (which itself has a predefined way
to know its length, whether that's because it's a fixed-size variable, or
the byte count is sent as a string, or something like that). Some rely on
something specific about the data itself; for example, strings that are
always null-terminated. Some use fixed-sized structures so that every
"message" is always the same size. And some even only allow for a single
"message" to be sent on a given connection; once a complete "message" has
been sent, the connection is closed (I'm not suggesting this is
appropriate for your design...just that it's an example of how some other
protocols work).

What you will do is entirely up to you, assuming you have defined your own
application-level protocol (which it appears you have). But you do need
to include something in your protocol so that the recipient knows when it
has received a complete "message".
And also, is this construction doesn't fix the problem of receiving
only a part of a message:

clientSocket.EndReceive(ar);
I'm sorry, I don't understand the above sentence.

Pete
Jun 2 '07 #5
On Sat, 02 Jun 2007 03:37:59 -0700, Cichy <ci*****@gmail.comwrote:
Ohh, and also I forgot to mention that sometimes my application
behaves in a strange way.
When I hit the "Automatic" button I'm receiving an error saying:

"demand of sending or receiving data was blocked, because socket is
not connected (and during sending over a socket datas when using "send
to" there is no address given"
I have to assume that text is the Message property of an Exception that is
generated, and that the text you've provided here is a translation of an
actual error message that is originally in some language other than
English. Is that correct? Because the text sure doesn't read the way I'm
used to seeing messages from .NET.
And when I hit OK the message is delivered to this specific Slave.
(???) (He receives a message with his unique number given to him by
Master).
Is the socket still connected after the exception? That is, do any sends
*after* the exception succeed?

It's not really all that unusual for an error for a given send to occur,
but for the data to still get through. In TCP, part of having a
successful send is that the data is acknowledged. Likewise, if an error
occurs, there's no guarantee that the data *didn't* get through. All you
know is that the complete "send/ack" process wasn't successful.

However, once you get an error on the socket, I would expect *future*
attempts at i/o to not work (depending on the error, of course...but the
one you're describing sure sounds fatal).

Pete
Jun 2 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Mike D | last post by:
I want to connect to an oracle database from my client pc, OS is win2k or XP. Can I connect to an oracle database without having the full oracle client installed? If so what would be the minimum...
2
by: Rick Strahl [MVP] | last post by:
Run into an interesting problem today with a client of mine: They have an ASP.Net form that they want to drive through a client side HTTP interface. I know a Web Service would be a better way to...
9
by: Harry Smith | last post by:
While reading the documentation on IsStartupScriptRegistered, there is a reference to "client startup script" as "Determines if the client startup script is registered with the Page object." What...
11
by: Andy | last post by:
Make the story short, I have a VB.NET client interface calling .NET webservice, written in VB.NET as well. I am trying to make the client as thin as possible so I let the webservice part to...
7
by: David Laub | last post by:
I've also posted this issue to a Sun/java formum, but since it appears to be an integration issue, this may be the better place to posr: I have written a dot net/c# Web Services doesn't fully...
7
by: Nalaka | last post by:
Hi, I created a sinple web service that returns a dataSet. Then I created a client program that uses this web service (that returns the Dataset). My question is, how did the client figure...
1
by: Mike9900 | last post by:
I want to use an interface in both the webservice and its client. For example, the web service implements an interface and then the client cast that webservice to the inteface. It seems impossible,...
5
by: Dinesh Kumar | last post by:
Hi all I am using VB.NET for a Connector dll in Delphi client and some webservice . can you tell me how to handle pointers in Vb.net which are passed by delphi client as parameters in function...
9
by: Paul H | last post by:
I have nearly finished work on a database for my client. At the start of the project we touched on the subject of reselling the database to other businesses in the same market as my client. How...
1
by: WebServiceSecurity | last post by:
The issue involves the following technologies: - 1. .NET 2.0 Framework 2. WSE2.0 (WS-Security) 3. X.509 certificates 4. BEA Weblogic 8.1.5
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.