I am writing a program where i run in a while (1) loop which blocks on a select call. My program listens on a server socket to which multiple clients connect. I also connect to a different server socket. So, i act as both the client and the server.
Its an event based design which only acts on events/messages it receives on its sockets. So far so good.
This design works and i have no problems with this so far.
My problem is that based on some message that i receive on a socket i call a function foo which runs in a for loop and does some work which takes up a LOT of time (say 40-50 secs). Now while i am doing this, i dont go back to the while (1) loop where i am blocked on the select call. During this period of 40-50 secs i dont act on any messages/events that i receive on the my other sockets.
Is there a way to break my foo function so that i process only some part of it and then go back to my while (1) loop, check the sockets, and if there is nothing there then continue processing the foo() function. My problem is that if there is nothing on the socket then socket call will be blocked and i will not be able to process foo().
I cannot use the time parameter in select as i already use that for some other functionality?
EDIT: Is this a normal design to get the main loop to run in a while (1) loop thats only blocked on a select call and does different things based on the messages that it recieves on the different sockets that it is connected to?
The usual approach here is to run foo() in a thread - that way it's independent of the loop. The loop just kicks off the thread.
What you should do is note somewhere that the thread is currently running or someone might send a lot of "start" messages which would lead your server to start more and more threads until it dies.
Another alternative is to split the "wait for commands" loop into a function which just does a single select and processes a single command which you might have gotten plus a loop which does call this new function endlessly.
That way, you can all the new "do it once" function from foo() every now and then.
You should create a thread to run your function, while the select will keep waiting for events.
Without threads, it would be complicated to pause & resume a process but you can do it just as a computer does: reserve some space to store the context of your processing when you exit foo. On the next call, it shall check for data to process in the context.
Also, maybe you should consider pushing sockets info into a pipe/queue of messages to be processed later.
About "time parameter" I guess you are talking about the select timeout. It can be used for different events but you have to work it out, i.e. compute the minimal timeout of all the events you are listening (and if you are in an infinite loop, you will have to re-compute it on each loop).
The best solution is to start a new thread (or even fork off a new process).
If you don't want to do that you can change your select to be non-blocking while you have work to do. You also need to call your select regularly.
int mySelectHandler(); // Returns false if SELECT would block
// Main loop
while (1) {
mySelectHandler(); // Check for new connections and messages
}
int bigWork() {
int prevStatus = <current select status, blocking or non-blocking>;
setStatus(NONBLOCKING);
for (<some condition)) {
<do some work>
while (mySelectHandler()) // Check for new connections and messages
;
}
setStatus(prevStatus);
}
There is a caveat with this approach: If there is a second call to bigWork() before the first call ends, then the first call will be delayed until the second call has been processed.
Related
I am writing a simple C game that accepts key inputs over the network. As it is my first time handling sockets in C, I am facing some problems with some functions. This function called 'recv', seems to wait for any network messages in the TCP connection until data is received. The problem is that since this 'freezes' the program while there are no messages, my normal game code that is supposed to run in an infinite loop won't work properly. Is there a way I could wait for network messages AND run the game at the same time?
while (1) //Infinite 'game loop' start
{
read_size = recv(newsockfd , client_message , 2000 , 0);
if(read_size > 0)
{
//Do something
}
//Game code here (Doesn't work when there are no incoming messages!)
}
The answer depends to an extent on what the background processing has to do and how frequently it has to run. If your background processing is a continuous task that needs to be running all the time and has no natural break, you probably need a thread. If it is simply something finite that must happen on a regular basis, you don't need a thread, you need poll or select.
poll is more flexible but select has an easier API but they more or less do the same thing. You supply a set of file descriptors, the events you are interested in and a timeout.
If you were using select in your case, you'd put your socket in the set of read file descriptors and supply a suitable time. When select returns, either your socket will have some data on it or the time out will have expired.
The advantage of using select over non blocking IO is that you can easily handle multiple sockets and instead of spinning in a tight loop when there is nothing happening, your process is suspended.
Use multithreading to solve this issue. recv function is blocking therefore you cannot use single thread for this operation.
Or use non-blocking sockets (no timeout).
thank you for reading. I'm currently implementing both the server and client for a socket server in C using linux. Currently i have a working "chat" system where both the server and the socket can send unique messages and the other end would receive that message with the correct length.
example output:
Server side
You:Hello!
client:hi, how are you?
You: fine thanks.
client: blabla
..And the client side would look be as follows:
server: Hello!
you:hi,how are you?
etc etc.
My question is, is there any way for the client/server to be able to send multiple messages before the other replies?
I currently have an endless while loop that waits for a receive and then proceeds to send, and this will repeat until the connection is lost. Using this method i can only send one message before i am forced to wait for a receive. I'm not sure of the correct implementation as I'm still quite new to both sockets and C! Thanks :)
Yes it could be possible.
The main body of your code, does not wait on socket for data. It reads the socket if data is already on it. It is possinle by using select function. After the select call, it reads the socket to display the received messages and sends user messages to other peer if there are ready on input.
A generic solution: You must use threading, and i'd propose to run the receiving part in a separate thread.
Hence, you first code the main thread to only manage sending, just as if the application couldn't receive at all. Apparently you have an edit field somewhere (and a messgae loop somehow). Each time the user presses Enter, you Send from within the Edit field's callback function.
Then you code a separate thread, that calls (and hangs on, blocks on) Receive(). Each time Receive "slips on" (ie. data came in), you do something with the data and then jump back to the Receive entry point. This goes on until you terminate the socket, or by other means decide to in fact not jump back to the Receive entry point.
The only situation where the two threads "touch" each other is when they both want to write text content to the same chat window. Both shall do it immediately as the transmission happens, but potentially both may try to access the chat window at exactly the same moment, causing a crash. Hence you muct apply a locking mechanism here; the one that first tries to access the chat window "gets it", while the locking mechanism keeps the other one on hold until the first releases the lock. Then the second one can do it's job. The locking is after all only a matter of microseconds.
These are immediate actions, free from each other. You don't need to que multiple messages; each one gets processed "as it happens".
Hello everyone i have a question about timeouts in c so i ask you guys.
So i'm making a server application in C that uses POSIX threads to accept multiple simpultenious connections but implementing timeouts was harder than i expected as i read the message (HTTP requests) in parts first the start line than the headers etc, etc, and i initialy used select() to detect if the socket was ready for reading but that way if the client sends the start line only than the server will continue waiting for the headers and body without ever timing out so what i did is i put all the code that reads the message in one function and i wan't to implement a timeout for the entire function, say if the function doesnt return in x seconds than a timeout function is called and the thread is exited...
[Things that i have tried]
putting multiple select calls (one for every socket read) but that ended up in a mess of having to calculate remaining time for each operation.
i didn't actually try to use an alarm signal as i've heard that signals effect the entire process and not a specific thread that would cause one time out to timeout every parallel connection..
thanx in advance.. B)
There is no proper way to terminate a thread function other than letting it finish.
Every attempt to finish a thread from the outside could lead to resource (mostly but not only memory) leaks, state variables in nondeterministic state, and so. Please don't do it. Never. The normal way of terminating a thread function from the outside is to make it listen to some means of inter thread communication (which can be a sync object, a volatile variable or even a message loop), and exit the function core when it is necessary. Normally you would realize it by having a single test in the cycle condition of the thread if it is looping or testing before every long-running operation inside your thread.
Now if you store the timestamp of the function start and test at every cycle condition/long-running test if currenttimestamp > timestamp + timeout, you can exit from inside your thread and voilá; your problem is solved.
I am implementing a multi cast server that sends a message every X amount of seconds to a multicast address.
I am also part of the multicast group and I will also receive messages from other senders in that group.
My question is, can I use sleep(X) to send my message while still receiving other messages from the group and process them? Or does sleep() block?
Sleep blocks all execution, but only in the thread from which you call it. I would suggest that you create two threads, one for broadcasting and one for listening. Then make sure that you synchronize any data shared between the threads with Mutexes.
When you call sleep(), only the calling thread gets suspended. All other threads will continue running, so you can continue receiving the data on the concurrently running threads.
Yes, sleep is blocking. You haven't said how you're implementing the server, but if it's in terms of a select loop, you should use the timeout argument to select, together with gettimeofday or clock_gettime and some arithmetic to determine when the next time you should send a message is, whether you've passed that time, and if not, how long until the time is up (which you can use for the select timeout). The timeradd, timersub, and timercmp macros can help with that.
I have an application that I'm working on that requires a couple of secondary threads, and each will be responsible for a number of file handles (at least 1, upwards of 10). The file handles are not shared amongst the threads, so I don't have to worry about one secondary thread blocking the other when selecting to see what is ready to read/write. What I want to be sure of is that neither of the secondary threads will cause the main thread to stop executing while the select/pselect call is executing.
I would imagine that this is not a problem - one would imagine that such things would be done in, say, a web server - but I couldn't find anything that specifically said "yes, you can do this" when I Googled. Am I correct in my assumption that this will not cause any problems?
For clarification, what I have looks something like:
Main thread of execution ( select() loop handling incoming command messages and outgoing responses )
Secondary thread #1 ( select() loop providing a service )
Secondary thread #2 ( select() loop providing another service )
As I previously mentioned, none of the file handles are shared amongst the threads - they are created, used, and destroyed within an individual thread, with the other threads ignorant of their existence.
No you don't have to worry about them blocking the main thread. I have used select in multiple threads in various projects. As long as they have distinct FDSETS then you're fine and each one can be used like an independent event loop.
Isn't select supposed to block the whole process?
Have you tried to set the nonblocking mode on the socket?
Also, see select_tut manpage for some help.
Here's a relevant section from the select_tut manpage:
So what is the point of select()? Can't I just read and write to my descriptors whenever I want? The point of select() is that it watches multiple descriptors at the same time and properly puts the process to sleep if there is no activity.