Implementing a network protocol

E

Erik

I'm implementing a program which uses a specific protocol to
communicate with other clients, but I was wondering how to implement
the protocol itself (in a well structured way). I already have a class
which handles the serialization and sending and receiving of messages.
So now I have to implement the protocol itself, but I'm not sure what
good way to implement this is. For example, is it a good idea to
implement the protocol steps in one function like this:
protocol(){
send req
recv response
if correct response
send file
else
send bye
}
or is it better to use some sort of state machine and let a function
handle the incomming messages:
handleMsg(msg){
if msg == req and state == 0:
do something
if msg == file and state == 1:
do something else
....
}

So my question is how do most programs implement there protocol?
Also, what is the best way to handle asynchrone messages (for example
sending
a msg while you also are waiting to receive a message)?

Thanks

Erik
 
T

tzvika.barenholz

A few quick bits of advice:
1) use the second of your suggested approaches. cleaner that way.
2) use Apache MINA to implement the client and server in a structured
way, without a lot of the hassle
3) make the handling of individual protocol messages stateless
whenever possible. easier to debug.

T
 
L

Logan Shaw

Erik said:
I'm implementing a program which uses a specific protocol to
communicate with other clients, but I was wondering how to implement
the protocol itself (in a well structured way). I already have a class
which handles the serialization and sending and receiving of messages.
So now I have to implement the protocol itself, but I'm not sure what
good way to implement this is. For example, is it a good idea to
implement the protocol steps in one function like this:
protocol(){
send req
recv response
if correct response
send file
else
send bye
}
or is it better to use some sort of state machine and let a function
handle the incomming messages:
handleMsg(msg){
if msg == req and state == 0:
do something
if msg == file and state == 1:
do something else
...
}

So my question is how do most programs implement there protocol?

I view implementing a protocol as related to implementing a parser
for a language. When writing a parser, you can do a recursive-descent
parser (which is like the first form above) or you can use a state
machine (like the second form above). Which one is best tends to
depend on the specifics (and that applies to both parsing and network
protocols).

If your protocol only has a small number of possible states, then the
state machine is probably a good choice. If your protocol has a lot
of states, then mapping the states to the call stack (i.e. structuring
it like a recursive-descent parser) might provide a natural way to
keep things structured and clear. Keep in mind, too, that exceptions
could be useful for handling errors, like an unexpected disconnect,
which is something that could happen at any point in time with a
connection-oriented protocol. That could be an argument for mapping
the protocol state to a thread's call stack.

Note that I mentioned threads. The style of mapping protocol state
to the call stack doesn't make a lot of sense unless each thread
handles exactly one session at a time. So the decision also
depends on your I/O and threading model.

Note that the best choice also may depend on the specifics of the
protocol itself. Is it a protocol which follows a question, answer,
question, answer, question, answer pattern and each side never
sends a new message while it's waiting for a response? Or is it
a protocol where either side could send a message at any time
and there might possibly be multiple logical requests or activities
going on at once? In the alternating question/answer case, you
can easily map that onto a call stack, but in the latter case,
trying to fit that structure to the call stack will probably only
make the program *more* confusing.

- Logan
 
G

Gordon Beaton

The protocol itself will mostly consist of alternating question/
answer, but a client can send a disconnect message at any time, so
the client must be able to send and receive messages at any time.

If your protocol is strictly request-response with the single
exception of the disconnect message, then I would say that you can
ignore that one exception and design for the other, simpler cases. I
presume that you don't need to stop what you're doing to reply to the
disconnect, or even reply at all.

Also, what do you gain by having a special disconnect message? Both
client and server need to gracefully handle any unexpected disconnect
by the remote party anyway, even if it isn't preceded by a cheery
"goodbye". As soon as you attempt to read from or write to the socket
you'll discover that the remote has closed.

/gordon

--
 
E

Erik

I view implementing a protocol as related to implementing a parser
for a language.  When writing a parser, you can do a recursive-descent
parser (which is like the first form above) or you can use a state
machine (like the second form above).  Which one is best tends to
depend on the specifics (and that applies to both parsing and network
protocols).

If your protocol only has a small number of possible states, then the
state machine is probably a good choice.  If your protocol has a lot
of states, then mapping the states to the call stack (i.e. structuring
it like a recursive-descent parser) might provide a natural way to
keep things structured and clear.  Keep in mind, too, that exceptions
could be useful for handling errors, like an unexpected disconnect,
which is something that could happen at any point in time with a
connection-oriented protocol.  That could be an argument for mapping
the protocol state to a thread's call stack.

Note that I mentioned threads.  The style of mapping protocol state
to the call stack doesn't make a lot of sense unless each thread
handles exactly one session at a time.  So the decision also
depends on your I/O and threading model.

Note that the best choice also may depend on the specifics of the
protocol itself.  Is it a protocol which follows a question, answer,
question, answer, question, answer pattern and each side never
sends a new message while it's waiting for a response?  Or is it
a protocol where either side could send a message at any time
and there might possibly be multiple logical requests or activities
going on at once?  In the alternating question/answer case, you
can easily map that onto a call stack, but in the latter case,
trying to fit that structure to the call stack will probably only
make the program *more* confusing.

   - Logan- Tekst uit oorspronkelijk bericht niet weergeven -

- Tekst uit oorspronkelijk bericht weergeven -

The protocol I'm trying to implement is quite simple and
does not have that many states. So some form of statemachine
is a good option?
The protocol itself will mostly consist of alternating question/
answer, but
a client can send a disconnect message at any time, so the client
must be able to send and receive messages at any time. Do
you know a nice way to handle this? I have thought about a background
thread which handles of the communication (sending and receiving) but
this isn't really an option, because receiving one message might take
some
time and I don't want other tasks to wait for one task.
Do you know if there are some nice tutorials or (simple) examples
which
show some different approaches?

Thanks.

Erik
 
E

Erik

If your protocol is strictly request-response with the single
exception of the disconnect message, then I would say that you can
ignore that one exception and design for the other, simpler cases. I
presume that you don't need to stop what you're doing to reply to the
disconnect, or even reply at all.

Also, what do you gain by having a special disconnect message? Both
client and server need to gracefully handle any unexpected disconnect
by the remote party anyway, even if it isn't preceded by a cheery
"goodbye". As soon as you attempt to read from or write to the socket
you'll discover that the remote has closed.

/gordon

--

Actually I not only a disconnect message can be send at any time, but
for example also a pause and resume message. How do you handle these
kind
of messages?

Erik
 
C

CHAFIK Wassime

Erik said:
Actually I not only a disconnect message can be send at any time, but
for example also a pause and resume message. How do you handle these
kind
of messages?

Erik
hi
IMHO for the resuming and pausing part of the protocol, i think of the
way FTP does it. You disconnect the socket but you can resume the
client/server "discussion" on a new socket, but this means that this
means that client and the server must implement a saveState() and
resumeFromState() kind of logic...
hope that it helps
sorry for my english...:)
 
J

Joshua Cranmer

Erik said:
So my question is how do most programs implement there protocol?

From what I can tell, most complex protocols use some sort of state
machine. A few network protocol RFCs show an overview diagram as if it
were a finite state machine (in ASCII art, as well!).
> Also, what is the best way to handle asynchrone messages (for example
> sending
> a msg while you also are waiting to receive a message)?

IIUC, I've heard pipelining used for these types of responses: the
requests are queued up and all sent and then wait for their responses.
Setting up a queue of responses and then processing them in turn would
be the way to go here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top