creating two sockets at udp server at a time, how to bind()? - c

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.

Related

select() issue with a push server - c/c++

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.

Is multithreading required when client and server want to talk at the same time?

I have two questions regarding using sockets for client server communication. Assume there is only 1 client in both the cases.
1) I know that we can send and receive data between client and server using a single socket. But in that case, what will happen when both the server and the client try to send the data at the same time?
2) Which of these is the best model?
i) Using single thread, single socket for sending and receiving
ii) Using 2 threads(one for sending and one for receiving), single socket
iii) Using 2 sockets and 2 threads, one for sending and one for receiving.
The connection is full-duplex, meaning that sends and receives can happen at the same time. So in answer to question one, both client and server will be able to send/read data from their socket simultaneously.
In terms of which "model" is best, it depends on your application and what you're trying to achieve. Incidentally, you don't need to multi-thread. You could:
Multi-process (fork)
Use non-blocking sockets (select/poll)
Use asynchronous notification (signals)
All of which have pros and cons.
For question number one, nothing special will happen. TCP is fully duplex, both sides of a connection can send simultaneously.
And as there is no problem with sending/receiving simultaneously, the first alternative in your second question is going to be the simplest.
In that scenario you dont need threads. The sockets themselves buffer the incoming data until you read it from the file-descriptor. More precisely there are multiple levels of buffers starting at the hardware. You will not miss data because you were writing at the same time, it just waits for you until you next read from the socket's file-descriptor.
There is no inherent need for multithreading if you want to poll at multiple sockets.
All you really have to do is use select().
To achieve this you define a FD_SET (File-Descriptor Set) to which you add all the sockets you want to poll. This set you hand to select() and it will return you all file descriptors with pending data.
man page for select, fd_set and a select tutorial

C/Linux TCP Socket Server

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?

Send same info to multiple threads/sockets?

I am writing a server application that simply connects a local serial port to multiple network connected clients. I am using linux and C for the server application because the equipment for the program is a router with limited memory.
I have everything setup for multiple clients to connect and send data to the serial port using a fork() process for each connection.
My problem lies in getting data incoming on the serial port out to the multiple (varing number) client connections. my problem lies in designing a way for each active socket to get all of the incoming data, and to only get it once. Any help?
Sounds like you need a data queue (buffer) for each connected client. Each time data comes in on the port, you post it to the back of each client's queue. The clients then read the data from the front of their respective queues. Since all the clients will probably read at different rates/times, this will ensure all of them get a copy of the data only once, and you won't get hung up waiting for any one client while more data comes in. Of course, you'll need to allocate a certain amount of memory for each connected client's queue (I'm not sure how many clients you're expecting, and you did say your available memory is limited), and you need to consider what to do if a queue gets full before the client reads all of it.
Presumably you keep a list or some other reference of/to connected clients, why not just loop over that for each bit of information and send it to all of them?
A thread per socket design might not be the best way to solve this. An event driven asynchronous approach should be a much better fit. However, if you must do it with threads, and given that serial ports are slow anyway, building a pipe between the thread listening to the serial port and all the threads talking to the network clients is the most practical. You could do fancy things with rwlocks to move the data, but you'll still need a way for the network threads to wait on both the socket and the data from the serial port, so you need to use file descriptors for both and something like poll.
But seriously, this would likely be much easier and would perform better without the threads. Think of it as a main loop which waits on poll which is watching the network and the serial port, determines which event occurred, and distributes data accordingly. It should be easier all around once you get the idea.

Distributed Networking Multiple 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.

Resources