I am currently planning an instant messagin program to help me leanr more about network programming, but I have a question about how I should lay it out.
You see the concept of sending plain text in packets is simple but I can't just call send and recv functions as the order of communcation is then hardcoded into the program. What I mean is if bob is talking to anne and bob tries to send two seperate messages in a row without anne sending a response, the program would not be able to handle that. So I wanted to ask how I would go about building in the capability for 'one-sided' conversations. I was thinking about forking the program so there was always a recv call waiting as well as a send. Is that a good idea or are there better ways of doing it, which are not overly complex.
maybe use 2 queues in your main loop: 1 for incoming messages and another for outgoing ones. the main loop communicate with the user interface. messages the user enters are pushed in the outgoing queue (a message object should include time, topic, body and so on). the incoming queue is checked and if a message is in it its displayed to the user. at startup time 2 other threads are spawned: the first one accepts connections from peers, reads there network messages, de-serializes them into message objects and pushes them into the incoming queue and then waits for the next connection attempt. the second one reads the outgoing queue and if a message is in it its serialized and a connection is build to the receiver and its sended to him.
maybe there are better designs out there, but in general
don't forget 3 things:
1. close your IDE now and write a functional spec. after this go on and design the technical details like classes, objects, their messages to each other, the network protocol state machine, message (de-)serialization algorithm ...
2. don't forget to secure the access to the queues with mutexes
3. do 1. first. really ;)
ok, I'll be honest, I didn't have something as complex as that in mind, but actually that's good, I will get started on learning about all the things you mentioned. Thanks a lot(<---No sarcasm there, I swear!). Just one more question, can you recommened an example structure for the queue? I am thinking of maybe putting in some string/char/indicator of some sort into the array which will hold buffered incoming messages to inform the main program that there isn't any new messages, but that seems a little clumsy to me.
Use the select() call to monitor several send() and recv() descriptors at the same time. Since select() also has a timeout feature, you need never get 'stuck' waiting for a response from a particular remote client say.
I, personally, would multi-thread that application and get a thread for receiving information, a thread for sending information and a third thread for all the rest (message handling, GUI, keyboard input..)
you can use the standard stl containers as queue, e.g. a simple vector<Message> will do the job. don't mess with arrays in c++ until you have to. the indicator that no message is in the queue just is vector::empty().
for your messages you can use a simple thing like this:
objects of that struct are just pushed in the vector if received or popped out of the outgoing vector if sended.
serialisation just means that if your sender thread is taking a message from outgoing queue he has to build a "linear stream" from the (structured) object. A really simple form would be for example
than you can pass reinterpret_cast<void*>(ss.str().c_str()) as buffer to your send() call to transmit the message to a socket.
ss << strlen(message1.sender_id.c_str() ) << message1.sender_id
<< strlen(message1.receiver_id.c_str() ) << receiver_id
<< strlen(message1.body.c_str() ) << body;
// the strlen-things in it announce how many chars of an message
// object attribute will follow. youl'll need them if your receiver
// thread is rebuilding (de-serialize) the message object
de-serialization just works the other way around. now the only thing I'll hvae to lern are threads:
oh and in the case you havent found it yet, the good old "Beej's Guide to Network Programming Using Internet Sockets"