I want to create a server socket but don't want to block my main application by the "accept call". So I will create a socket in main application. using pthread mechanism I created a new thread in which I will use "accept call" in it. After creating socket in main application, I called "pthread join". Now when this thread executes, "accept call" is again blocking the main application. I checked using gdb. How I should go about this problem?
One way would be to make the main server socket descriptor as non-blocking and use select system call. When select returns and the main socket descriptor is having data, create a new thread to handle the newly accepted connection. This way you can achieve parallelism, The new connection, which was created will have it's own context and will be scheduled as and when possible even though while accept() waits for a connection.
Related
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.
To begin with, I know there are ways to handle multiple client requests by forking or threading. But I cannot understand why there cannot be multiple acceptance by the server without forking or threading. accept() call can simply accept all process wish to connect to it. Why cannot the the call(accept()) go on unless a client cut its connection??
server does socket(), listen() and bind() with blocking(default) way
client does likewise by default socket() and connect()
What I think is accept's returned value will be for the recent child. But in reality it blocks until the prior client(s) cut its connection.
I wonder whether there is file-descriptor which is returned by accept() overwriting? If not, how?
There is no overwriting; accept() creates a new connected socket, and returns a new file descriptor referring to that socket - a new, distinct one each time. Of course, a server which manages all client connections without creating other threads must store all those file descriptors, e. g. in an array.
I have GUI application this application starts server by calling
start_server() function. Then there is created TCP passive socket receiving incoming connections in the server loop(we have connection sockets here) and handling them on multiple threads simultaneously.
Now I need some end_server() function that force server and all connections to close. What is the best practice to close such servers.
I consider doing this in such way:
pass to start_server() function some server_info_t structure.
then when passive socket is created its descriptor i stored in server_info_t, there is also stored its binding port number
in server_info_t structure there is on_server_start callback that is called asynchronously after server has been created correctly returning some information about created server like port number on which server is listening (this enable to change GUI controls like status icon from red to green)
then i pass the same structure server_info_t info server_loop and there where new connection from client is coming I will take the connection socket and store its descriptor inside server_info_t structure some linked_list_t or hash_map_t of connection sockets.
now i can invoke some asynchronous callback like on_client_connected and pass handling of connection (connection socket) to another function (separate thread from thread pool), and then server loop waits for next connection. I also need to pass server_info_t structure here to remove connection_socket descriptor from linked_list of conn socket descriptors it connection handling for given client finish.
Here inside struct server_info there can be another callback function on_client_disconnected
Now outside this multithreaded server running in the background I have a GUI app that started the server, and it has the pointer to server_info_t structure that stores all information about server: port number, passive socket, linked_list of actually connected connection sockets (active sockets), callback functions pointers that should be called to inform about server events, etc.
So I think I could then make end_server(server_info_t) (ex. when user clicks STOP in GUI application user interface) and heres the magic happens... server stops. But how?
Should I take all connection sockets (while iteration over linked list in server_info_t structure) and close them using (shutdown + close), and then shutdown + close passive socket?
Then I could even call some callback on_server_end which pointer I found in server_info_t structure.
Should I use some mutex to synchronise access to this server_info_t structure?
Should I use some mutex to synchronise access to this server_info_t structure?
You definitely should synchronize access to the shared data structure.
Should I take all connection sockets (while iteration over linked list in server_info_t structure) and close them using (shutdown + close), and then shutdown + close passive socket?
This is kind of quick and dirty solution. Better design is to inform worker thread the connection should be closed. In this case you can:
Inform clients of the server about reason of the connection shutdown
Complete process of current request
Way to solve "inform" task can be different:
If you use select/poll/epoll methods you can use designated socket (for ex. socketpair) to indicate stop
If you use blocking calls you can use pthread_cancel mechanisms but they are very system-dependent
If your worker thread wakeups periodically you can use kind of atomic flag
i am programming a Mulithreaded Client/Server between processes program which uses message queue's.
The Server will handle the message's send by the clients, and later it should give the work to a threads to continue handling their it's processes.
Every client will have a different message queue.
After making the connection of the 1st client and sending a thread to handle it
Using pthread_join doesnt allow me to to receive new connections that are on main thread,cause it's blocked how can i fix it.
Receiving New Messages in the main thread ( or other solution if possible)
Sending to threads to handle a client message's and after.
Getting back to receive new message
Very simple,
Make the threads you create detached from the main thread - means you don't need to "pthread_join" them anymore. So the main thread is getting new connections and new request for existing connections in a loop, if it's a new connection it will start new thread and if it's a request to an existing connection it's just add the request to the thread's queue (using a lock on it's mutex ofcourse).
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.