i have this question, that i think is more theoretical than pratical.
I have a server, that receives connections from clients, with select() function.
Server has a pattern master-slave where slave are threads that take file descriptor from master and manage request from specific client.
(Every request from client start with a connection request)
I think that select() function must understand that same client asks some requests, because if same client asks two requests and select function can't understand that is same client, select create two file descriptor for same client with accept() and after two different threads manage a different request from same client and i think this can create a lot of concurrency problems because different threads write in different file descriptors but the real channel with client is the same.
So, i would like to know, how can select() recognise a client after the first request?
Related
I have a multithreading TCP server that waits for a number of predefined clients to write something to the server side and base of the requests, the server will write a message to all the clients based on their request. I'm stuck at the part when the clients that already sent a message must wait until all the clients have sent their respective message. How can I do this? I attempted to write 2 different thread functions, the first one calling the second one but not sure if this is the right way. Is there a way to make the clients wait until the server writes to all of them?
I'm writing a server in C ++ for both Windows and Unix systems.
A key feature of this server is that it must be able to receive and send network packets at any time.
Specifically, the server must be able to send data to the client not only in response to their messages, but also be able to send packets to them asynch in push.
I'm having difficulty in implementing a solution that uses the select() function in the scenario described above.
The solution I have currently implemented does not convince me at all and I think it can be implemented with better patterns/solutions.
I currently have a dedicated thread (selector) that performs the select by listening on events in the reading for the server socket (to accept new connections) and for the sockets connected to the server.
This is the main select() loop:
if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}
This solution works well for receiving the data and to respond to client requests in synchronous form.
However, the server must also be able to send asynchronous data, and send when necessary, packets in push.
To do this I currently use separate threads that perform directly the send() on the client sockets.
This solution does not convince me, and I would like to centralize the packets receiving and sending on the selector thread.
The main difficulty is that the select() by its nature is blocking and I have no control until a client does not send any packet or the timeout is triggered.
The solution to set a timeout very low does not convince me; I see it as an easy solution that is actually doing active wait, and not only, however, the worst case I would pay the price of the timeout before sending the push packet.
I thought a more 'elegant' solution; I think, will work well, but only for a Unix/Linux platform.
I thought to use an anonymous pipe and insert into the select() read_FDs_ the anonymous pipe read descriptor.
In this way, when a thread wants to send a data in push, it writes something on this pipe, interrupting the select() and returning control to the selector that can then predispose to send the data to the client, without significant loss of time.
I think that this solution, unfortunately, cannot be implemented on Windows because the select() function on that system works only with fds that are actually sockets.
So the question is: Is there some well known solution that can be used to address this kind of scenario (both Linux and Windows)?
You can create a self connected UDP socket, this works equally well on Windows and Linux.
Basically, you create a UDP socket, bind() it to INADDR_LOOPBACK and port 0, and connect() it to itself (with the address taken from getsockname()).
At this point, you can send yourself a single byte message (or something more specific) to wake yourself up.
I want two functionalities to be implemented on my udp server application.
Creating thread that continuously receives data coming from any client.
Creating a thread that continuously sends data on server socket after specific time period and waits for reply from client. (I implemented this to make aure that whenever any client goes down, the data is not received back from client and server comes to know that client is down.)
Now, the problem I am facing is that since two threads are sharing same connected socket, whenever both threads try to access this socket simultaneously, a deadlock is established.
One of the solution I found was to create two sockets. One that continuously receives data, and the other socket that is meant for sending data from server time to time to clients and wait for their response, but since Server can must be bind()ed and I have bind()ed my socket to INADDR_ANY once, how would I create a separate socket for sending data from server and waiting for replies from client.
Please help me with this complication.
Also do let me know if there is some other better way of its implementation.
Thanks in advance :)
You will have to use non-blocking net functions and use a mutex to ensure no two threads access the socket at once.
A single thread may, however, be enough, if you use non-blocking functions. Using many threads will probably not improve performance, but may make the code more readable.
I'm implementing a TCP socket server in C and Linux. It will be a chat server handling many requests simultaneously. Here is the pseudo code for how it is setup
create a socket
bind to a well-known port
use listen to place in passive mode
while (1)
{
accept a client connection
fork
if (child)
{
communicate with new socket
close new socket
exit
}
else
{close new socket}
}
From what I've seen, the "communicate with new socket" part consists of reading the buffer and then possibly writing to the buffer, then the socket closes. I thought sockets were suppose to be a persistent connection? If the client has to reconnect every time it wants to send more data to the server, isn't this inefficient and defeating the purpose of sockets?
If the client has to reconnect every time it wants to send more data to the server, isn't this inefficient and defeating the purpose of sockets?
It's impossible to say without knowing more about the nature of your application:
In some cases, it makes sense to maintain a persistent connection for the duration of the client's lifetime.
In other cases, connecting on every message would also work well.
You are quite right on the efficiency front: there is quite a lot of overhead involved in establishing a TCP connection. Therefore, if the messages are frequent it may turn out to be very costly to set up a new connection for each message.
Don't close the socket. Put the code which receives and responds to the messages in a loop and using blocking I/O ( the default ) to block on reading the socket until a request arrives. This way you'll have a forked process dealing with each client and using minimal resources. You only close the socket and exit the child process when the client explicitly closes the connection because it's done.
Use UDP instead of TCP. This way there is no "connection" between the server and the client. You multiplex multiple clients to a single socket without forking. If you care about reliability you'd need to add a sequence number to each message to keep them straight and allow retransmission on failures.
Keep a single process using TCP, but store a socket descriptor set and use select to check for readable sockets. You can then retransmit that data on each or some of the other client sockets.
I'd point out that forking a child for each client in a chat server seems like a poor implementation. How do two people who want to chat communicate? Each one will be served by a separate process - how do the processes communicate with each other so that chat data can pass between clients?
I'm currently working on a distributed networking project for some networking practice and the idea is to send a file from my server to a few different clients (after breaking up the file) and the clients will find the frequency of a string and return it back.
The problem I'm running into is how to identify each client and send data to each one.
The solution I've been working on to identify each client by their port. The problem arises as to how I handle multiple connections and ports. I know I have to use send() to send the data to a port once I open a connection and etc. but I have no idea how to do this across multiple connections ( I can do this with a single client and server but not with multiple clients)
Does anyone have any suggestions from a high level standpoint? I got one suggestion from a friend who said:
Open a socket
Listen for connections
When a connection request is received, spawn a new thread to handle the connection.
The main process will go back to step 2 to listen for new connections, while the new thread
will handle all data flow with the associated client.
But I'm not really sure I understand this... I've also been referencing http://shoe.bocks.com/net/#socket
Thanks
Your friend is correct. Follow first three steps (mentioned by him) and then you need to:
After spawning thread, send data (read from file) to new socket.
Once entire file is finished, you should disconnect and exit thread. On client side, you should handle disconnect and probably exit.
NOTES:
Also, you can use sendfile() instead of send() if you wish. You can use select() if you wish to handle all connections without spawning threads.
Refer http://beej.us/guide/bgnet/ for details.
EDIT:
how to identify each client? Ans: This is classical port discovery problem but in your case its simple. Server should be listening on well known port (say 12345) and all the clients will connect to it. Once they are connected, server has all sockfds. You need to use these sockfds to send data and identify them.
If you check out networkComms.net, an open source network communication library, once you have created a connection with a client you can keep track of that specific client by looking at it's NetworkIdentifier tag, a guid unique to each client.
If you will be sending large files to all of your clients also check out the included DistributedFileSystem which is specifically designed for that purpose.