Checking if server process is listening on domain socket or not - c

I'm writting client-server programs, that using unix domain socket for communicating between two sides.
The requirement is:
Server opens an abstract socket on a given address, then listen on that. By some triggers, server can stop listening on that.
Client has to monitor that Server is listening on given address path or not
if server is listening on socket then send a register request to server
if server close the socket then do some action cleaning up...
To check the server is listening or not, my solution is:
Periodically create a socket and connect to server address path, if succeed, then means that server is listening, and vice versa for any case of error.
But the solution seems to be cpu-consuming if checking interval is too short.
Then my question is: do we have any method like registering some callback to system, and get the notification whenever some process starts/stops listening on a given address? or some other better suggestion...??
Many thanks,

Related

UDP client-server with select

I'm trying to realize a UDP client-server application in C using select function. I use it in the client to monitor both stdin and socket streams, and it works. In the server, I've a socket to listen requests from clients, and every time the server knows a new client I save a struct with client port, IP address and also create a new UDP socket to manage this communication with a single client and I also save the descriptor of this new socket in the previous struct. In the server, the select function is used to monitor the different socket descriptors, so the answers from server to clients are sent on an "exclusive" socket for each client. So I want to know if the select in the server is enough to realize a concurrent server, able to manage concurrent requests from different clients, and to serve it simultaneously, or I need to use a thread for every client in the server? Can someone help me? thanks.

Can a server directly connect two sockets that it is connected to?

Say I have a public server on the Internet, written in C, that is connected to two independent clients. Both clients initiated the connection. One client is (e.g.) an iOS app, the other is a native Windows app.
The purpose of my server is to allow these clients to send text messages to each other. Client 1 sends a message, the server receives it, and then forwards it onto Client 2. The same thing happens in reverse when Client 2 sends a message.
This feels inefficient. What I would really like is for both of these connections to contact the server and then for the server to connect these two clients directly to each other - after which my server can forget both clients as they are responsible for communicating with each other. My server is then free to connect up other clients in the same way.
My question is: is this even possible (with TCP and/or UDP)? Neither client necessarily has a public IP address, which is why they have to initiate the connection. Once the connection is established however, my server knows the connection address of both clients. Is there a way to connect them together? A syscall that can do this sort of thing, perhaps?
No, you can not join two existing TCP connections to one.
There are 2 options:
1) Keep your server in the middle as it already is. It should not be problem, if you don't have thousands of clients under one server.
2) Server could send control messages to clients, and order those open new TCP connection between each other. Server should also make decision which of the two clients must be initiator of the new TCP connection.
Option 2 is problematic, because client may have firewall rule that prevents in coming connection to the wanted port. Also NAT would cause problems.

UDP server, how can do that each thread will receive the right client's packet and not others?

Well, i have to do a udp server in C on linux.
This is my issue, for example:
I have that each thread will manage a client. But recvfrom will accept packets from any source, so, how can do that each thread will receive the right client's packet and not others?
I hope I explained my issue well.
Thank you!
(I mean that my server will make a new thread for each client that want to be served. So with TCP i can use accept to have a "dedicated" socket for each thread-client connection, but with UDP i can't do the same.)
You can't have multiple threads reading from the same socket at the same time.
What you should do instead is either:
have a dedicated thread that receives all inbound packets, looks at the source IP/Port, and routes the data to the appropriate processing thread as needed.
give each processing thread its own socket that is bind()'ed to the same local IP/Port and connect()'ed to the particular source IP/Port it is interested in, then each thread can call recvfrom() independently and it will only return packets that match the source that the thread is expecting.
UDP is a message based connection-less protocol. Here, there is no definite connection / setup done between the client and server prior sending the data. It does not maintain any states for communication at either client or server. UDP uses datagram socket(SOCK_DGRAM) . This ensures each packet sent or received in any order but with preserved message boundaries.
TCP is a stream based connection oriented protocol. Here , a definite logical connection is setup between the client and server prior to the exchange of data. TCP states are maintained for communication. TCP uses stream socket(SOCK_STREAM). This provides a connection-oriented, sequenced flow of data with mechanisms for creating/releasing connection and for detecting errors.
In header of TCP and UDP , only port number will be present. It is the responsibility of the IP header to add the necessary destination IP address for routing. However the source ip address shall be obtained from the source host.
In both TCP server and UDP server, once the socket is created using the particular socket type, it is bound to the port using bind system call. This is done so that the client can address to this port of the server. The procedure of binding is not necessary in either the TCP client or UDP client, because it does not matter in whatever port the client communicates. Till this point, it is same for both TCP server and UDP server.
In the case of TCP server, the listen system call will be invoked to listen for connections on the particular socket. The listen indicates the limit on the number of connections that can be queued up and that the server process is ready to accept any new incoming connections on the socket.
The server calls the accept system call which is a blocking call that waits for incoming connections.
Once a new connection comes, a new socket descriptor is created and the connection gets established between the server and client. However, as server, it has to keep listening for new connections.
This is where the multiprocessing begins to get into picture. Since connections can be triggered by any client at any time by using connect system call, we need to have the accept call(blocking call)for the new connections. Further, to have these new connections processed in parallel, one option is to fork and create a child process which will in-turn take care of further processing of the new connections while the parent process waits for new connections on accept call. This is how individual client connections are identified and processed/handled in the server. In simple terms, in concurrent server architecture, there will be one listening socket and multiple connected socket end points at the server at any time.
Note : The connect system call from client triggers the TCP SYN from client for starting the 3 way handshake procedure. At this point of time, the client socket state is SYN_SENT and once the SYN reaches the server, the server socket state is SYN_RCVD. Then the server responds with SYN_ACK to client for which client will respond with ACK and this establishes the connection between client and server.
In the case of UDP server, there is no need for this initial connection establishment as it is a message based connection-less protocol using datagram socket(SOCK_DGRAM). So, UDP client will not need the connect call for connection establishment which turn strips off the need for listen and accept calls in the UDP server. So, the UDP client server architecture shall be a iterative architecture where every client request/response shall be sequentially processed as iterative server architecture are applicable for services like UDP(light-weight) that consume less processing time. Also note that since the time consumed for processing is less, iterative servers will be state less.
In the case of requirement of multiple threads listening on same socket, you can also go for select or epoll system call based software architecture, where every thread will be waiting on select call but in this scenario, it may not be of great help. An alternate design that can meet your requirement can be a combination of separate thread for receive,parse & dispatch that will direct multiple processing threads.
That's why you have a port number.
If your server is listening on say, port 8080, no other process will be allowed to bind a socket to that port.
All clients that want to connect to this server will need send their data to port 8080 on the server's IP.
The UDP datagram has a source IP and port - you know where it came from, so you can route it appropriately.
You may well need a dedicated thread to send to the port, maintain state and later match up replies with requests so that the originating thread can be signaled that it's own reply is available. This could be done by providing a callback in the request struct that the rx thread signals when the matching reply arrives. The callback could signal a synchro object that the originating thread is waiting on.

c linux sockets: check for existing connections from client side

I have the following setup:
2 Ubuntu machines (server and client)
on the "server" I'm running this to echo all the data received back to the sender (the client):
ncat -e /bin/cat -v -l 12345
on the client I have simple application which just connects to the remote socket: socket() -> setsockopt() -> connect()
So... my question is: Is it possible to check if there are other applications already connected to the socket from the client application? I want only one process connected to the socket at any given time and I want to check this from the client application. Is this possible? After 3h googling I couldn't find anything relevant :(
(sorry, no experience with network programming)
No, a client is not able to see how many other clients are connected to a server.
To be able to retrieve this information an application specific protocol needs to be used on client and server.
Anyhow there is this one special case: If the client knows that a maximum of N clients can connect to the server, and it's own try to connect is refused it could assume that N clients are connected to the server already.
To set the maximum number of connections ncat handles in parallel use it's option -m/--max-conns. Verbatim form man ncat:
-m numconns, --max-conns numconns (Specify max number of connections) .
The maximum number of simultaneous connections accepted for an Ncat instance. 100 is the default.
Run:
netstat -an | grep <your server port port number>
on your client machine to see any existing TCP connections.
Can you not close the listening socket on the server after you've accepted one client? If there's no listening socket no more clients will be able to connect. Once you've dropped your one client, you can then open the listening socket again, ready for one more. That way the client will see a "failure" to connect if the server is busy, or will succeed normally otherwise.
The down side of this approach is that the client won't be able to determine exactly why it can't connect, it could be because the client is busy (has its one client) or it could be because of other issues. Does this matter?

Do TCP connections get moved to another port after they are opened? [duplicate]

This question already has answers here:
Does the port change when a server accepts a TCP connection?
(3 answers)
Closed 8 years ago.
If a TCP socket server listens on port 28081 for incoming connections and then accepts a connection and start receiving data. Is the port that data is coming into still 28081 or does the port get changed.
for example what port does the incoming data come to in the pseudo code below? Is it still 28081 or does the OS assign a new port?:
bind
listen (on port 28081)
while 1
fd = accept
fork
if child process incoming data
A TCP connection is uniquely identified by two (IP address, TCP port) tuples (one for each endpoint). So by definition, one can't move a port or IP address of a connection but just open a different one.
If the server binds to port 28081 all accepted connections will have this port on the server side (although they most likely will have varying port numbers on the client side).
For example, if two processes from the same client machine will connect to the same server, the IP address and TCP port on the server side will be the same for both connections. On the client side however, they will have two different port numbers allowing the operating system on both sides to uniquely identify which process and file descriptor the received TCP packets should be assigned to.
Yes, it stays on that port, though some protocols (FTP) might open a second connection on another port. Dont think of a port as a physical path or plug, like a USB port that can only have one thing plugged into it. But rather think of it as an identifier for the service being requested.
Often, though, the new socket connection is passed off to another thread which handles the read/writes for that specific connection.
There can be more than one client connecting to one port, as the connection is identified by both the server and client IP address and port. So, accepting the connection from one client does not block others from connecting. You could even connect another time from the same client (using another client port).

Resources