Libevent: how to close all open sockets on shutdown? - c

I have created a simple HTTP proxy using libevent. It can be shutdown by sending it a SIGHUP signal which is caught by the signal handler. The shutdown function calls event_base_loopexit, frees structures and other heap allocations and exits.
The problem is if a SIGHUP is caught when a connection is open. I need to be able to close the socket, ideally invoking the same close function that is called when a close event is caught.
Is there a correct or standard way to do this?
At the moment, the only thing I can think of is to keep a linked list of connections and simply iterate through this on shutdown, closing each in turn.

At the moment, the only thing I can think of is to keep a linked list of connections and simply >iterate through this on shutdown, closing each in turn.
That's what you have to do.
(Note that sockets are closed when the application exits. But if you need to do custom logic on all the connections on shutdown, you need to keep track of them and iterate through them.)

Related

Closing concurrent server socket (TCP)

I'm making a concurrent server/client program in C using threads. Whenever a client connects, I create a new thread to handle it.
My problem is: I want to be able to close the server, from the client. With the command '..' for example. When I type '..' in the client, I want the server to close immediately.
I thought about having a global variable, that indicates wether the server should close or not. The problem is: When the thread is created to handle the client, the main thread goes back to accept(), and it cannot check that variable. So, it will only close when a new client connects.
Any ideas on how to solve this?
Thanks!
Use select() or (e)poll() or equivalent to wait for a client to connect BEFORE you then call accept() to accept the connection. Those kind of functions allow you to specify a timeout, that will allow you to stop waiting periodically to check for other conditions, like a shutdown request. On some platforms, you can even have these functions wait on not only the listening socket but also a separate pipe that you create privately for yourself, and when you want to "wake up" your waiting loop to do something, simply write a byte into that pipe, and when the loop detects that byte arriving then it can act accordingly.

Forking a child or threading?

I have a server-client system..where each clients mmap the file found on the server. As soon as a client updates the file, the server needs to notify the clients to update their file..i.e. they should unmap and mmap the file again. I thought that a solution to this problem is to send a string "Update" to the client by using write() (in the server side)..and do an infinite while loop to continue waiting for such "Update" by using read() (in the client side). However, this while loop should be in some sort of thread or child process. Which is best? and any other suggestions please? Much appreciated. Thanks in advance.
Look into using sockets and the select statement. With a setup like this you can make event based programming
The server could send a signal which the clients would trap and act accordingly.
Just take care of what your signal handler will do (there are many functions that are not safe to call in the context of signal handling).
Also be aware of race conditions and careful to not lose signals.

Socket Programming - Having a process with both client and server code

I am writing a socket program which consists of a bunch of slave processes that will be sitting on each machine in a cluster of computers, while a master process instructs them to move local files over to remote slaves on remote nodes. The primary task of these slave processes is to read files off their local hard disks and transfer them to other slaves on other machines. I want to have this functionality of both listening for file data and sending over file data built into a single process.
Is it possible that I can have both the sending and the receiving bits in the same process ?
//I want this to send a connect() request to every other slave node
initialize_Connections();
//Have an accept() call for accepting the connection requests from the other nodes
accept_Connections();
Is it even possible to pull off something like this ? I looked at forking the process between the initialize_Connections() and the accept_Connections() call (ie a child process calls the initialize_Connections() and the parent takes care of the accept_Connections()) but that did not work out for some mysterious (to me) reason.
Is it possible to use nonblocking connect() and accept() in this situation ?
using threads is not mandatory, you just need to setup one listening socket that fires a socket for each incoming connection and a bunch of sockets for the connections versus the other clients, and pool/select on every socket for events...
The select() call allows you service multiple sockets without entering blocking calls. It requires you to set up some structures that get populated by select(). You call select() iteratively, examining the structures to see if reading &/or writing to one of the specified sockets would succeed immediately. Then, you can call read() or write() on an open socket without fear that it may block indefinitely.
Is it possible that I can have both the sending and the receiving bits
in the same process? Is it possible to use nonblocking connect() and accept() in this
situation ?
Yes, absolutely. You can do it with multiple threads, or with just a single thread using select() or poll() to multiplex non-blocking I/O across multiple sockets.
Neither of these approaches is trivial to get 100% right, but they are quite doable. If you'd like to avoid spending a bunch of time learning (and debugging) multiple-connection socket programming details, I'd recommend using some middleware that does this sort of thing for you, rather than rolling your own. I'm partial to my own library that I wrote to handle this sort of thing, but there are other good ones out there as well.
I would have each slave process execute on two permanent threads. On one thread, the process would connect to the master process and then receive instructions on which file to send to which other slave processes. For each other slave process in an instruction, this thread would create a temporary thread to send the file. On the other permanent thread, the slave process would receive connections from other slave process. For each connection it would create a temporary thread on which the file was received.

C - simultaneous receiving and handling data from unix sockets

I have a C program which communicates with PHP through Unix Sockets. The procedure is as follows: PHP accepts a file upload by the user, then sends a "signal" to C which then dispatches another process (fork) to unzip the file (I know this could be handled by PHP alone, this is just an example; the whole problem is more complex).
The problem is that I don't want to have more than say 4 processes running at the same time. I think this could be solved like this: C, when it gets a new "task" from PHP dumps it on a queue and handles them one-by-one (assuring that there are no more than 4 running) while still listening on the socket.
I'm unsure how to achieve this though, as I cannot do that in the same process (or can I)? I have thought I could have another child process for managing the queue which would be accessible by the parent with the use of shared memory, but that seems overly complicated. Is there any other way around?
Thanks in advance.
If you need to have a separate process for each task handler, then you might consider having five separate processes. The first one is the listener, and handles new incoming tasks, and places it into a queue. Each task handler initially sends a request for work, and also when it is finished processing a task. When the listener receives this request, it delivers the next task on the queue to the task handler, or it places the task handler on a handler queue if the task queue is empty. When the task queue transitions from empty to non-empty, it checks if there is a ready task handler in the handler queue. If so, it takes that task handler out of the queue, and delivers the task from the task queue to the task handler.
The PHP process would put tasks to the listener, while the task handlers would get tasks from the listener. The listener simply waits for put or get requests, and processes them. You can think of the listener as a simple web server, but each of the socket connections to the PHP process and to each task handler can be persistent.
Since the number of sockets is small and persistent, any of the multiplexing calls could work (select, poll, epoll, kqueue, or whatever is best and or available for your system), but it may be easiest to use a separate thread to handle each socket synchronously. The ready task handler queue would then be a semaphore or a condition variable on the task queue. The thread that handles puts from the PHP process would place tasks on the task queue, and up the semaphore. Each thread that handles ready tasks would down the semaphore, then take a task off the task queue. The task queue itself may itself need mutual exclusive protection depending on how it is implemented.

Socket programming accept() in C

Okay I'm brand new to socket programming and my program is not behaving like I'd expect it to. In all the examples that I see of socket programming they use accept() and all the code after assumes that a connection has been made.
But my accept() is called as soon as I start the server. Is this supposed to happen? Or is the server supposed to wait for a connection before executing the rest of the program?
EDIT: Oops I forgot to mention it is a TCP connection.
I think this is what you're after.
http://www.sockets.com/winsock.htm#Accept
The main concept within winsocket programming is you're working with either blocking or non blocking sockets. Most of the time if you're using blocking sockets you can query the sockets recieve set to see if any call would result in your call to the routine being blocked..
For starting off with this UDP is easier considering its a datagram protocol. TCP on the other hand is a streaming protocol. So it's easier to think in regards to blocks of data that is sent and received.
For a server, you:
Create the socket - socket().
Bind it to an address.
You enter a loop in which you:
Listen for connection attempts
Accept and process them
It is not clear from your description whether you are doing all those steps.
There are multiple options for the 'process them' phase, depending on whether you plan to have a single-threaded single process handle one request before processing the next, or whether you plan to have a multi-threaded single process, with one thread accepting requests and creating other threads to do the processing (while the one thread waits for the next incoming connection), or whether you plan to have the process fork with the child processing the new request while the parent goes back to listening for the next request.
You are supposed to enter your acceptance loop after you have started listening for connections. Use select() to detect when a pending client connection is ready to be accepted, then call accept() to accept it.

Resources