Passing control information between client-server in socket programming in C - c

I am coding for a server-client programming in C using socket API where I am trying to send control information to client for using different TCP connection.
Whenever the server has created new socket(TCP), I want it to notify the client to use the new socket for further communication.Currently I have thought of sending UDP packet to the client to be notified. Once the client receives the packet, it sends back the ACK to the server and at the same time switches to the another TCP connection.
I want to know, is there a better to communicate the control data across the network besides using UDP as it is unreliable.Thnx
I would like elaborate on what I am trying to achieve. I am going to measure the parameters like bandwidth,latency, receive window etc. as metric for a Ipv4 and IPv6 TCP connection. Based on the observed performance I will be switching between the two protocols whoever provides better performance.Once the decision is made to switch , I have to notify the partner(may be client or server based on type of bandwidth I am measuring upload, download). I start with IPv4 connection and at the same time open another connection - IPv6 for measuring the bandwidth and latency.
If the IPv6 connection provides better performance, I need to tell the client to switch to IPv6. In this case both the connections are open for monitoring the bandwidth periodically to decide on switching. So I have two queries on this aspect. 1.Is it a good idea to keep two connections at a time.I can create the other connection only when I need to measure the metric as the path followed between two machines will hardly change.If yes, I can pass the control information using the other TCP connection to tell the client to switch. In this way I can also measure the bandwidth and notify client
It it is not a good idea two have two TCP connections, I can use UDP to send the control information. I am avoiding to send control information on the conn used to transfer actual data as it will be an overhead. My code will work like a middleware for transfer the data, where the application will call my functions/macros to transfer the data, and the internal code will take care of measuring the bandwidth and decision to switch.I hope I am clear on what I want achieve. Thank for your feedback in advance

The normal sequence of operations for a server-side listening TCP socket is:
int fd1 = socket(...); // Create socket - assuming TCP, not UDP
bind(fd1, ...); // Bind it to a local address
listen(fd1, ...); // Set it in listen mode
int fd2;
while ((fd2 = accept(fd1, ...)) != -1) // Accept an incoming connection
{
...communicate with client via fd2...
close(fd2); // When finished
}
close(fd1);
Now, at the point when you get fd2, that has a socket with a different local ephemeral port from the port that fd1 is connected to (correction per EJP). There is no need to communicate any specific information back to the client; the TCP/IP implementation deals with that for you. The client will have a socket that is connected to fd2, with a port (probably an ephemeral port) on its machine connected to the server and the server's ephemeral port.
The point is that the completed connection will have a unique 4-tuple of (client IP address, client port, server IP address, server port).
When it comes to the processing, there are various ways of dealing with it. You can use an iterative server which deals with one request before dealing with any others. Or you can create a concurrent server in either of two different ways. One way is with a threaded server where a thread (from a pool, or newly created for each incoming connection) deals with the new request while the main thread goes back to accept new incoming requests. The alternative is that you create a forking server where the main server process forks and the child process deals with the new connection while the parent process closes the connection and goes back to listening for the next connection request.

Related

Trying to get sockets with the same address and different ports to pass data back and forth

Firstly, please excuse my probable butchering the technical terminology. I've been thrown into socket IO with little formal education and I know that I am bungling words left and right.
I'm trying to build a client and server in C that enables multiple clients to connect to one another. The general procedure goes something like this:
1) Server has one port that is constantly listening and accepting connections
2) A client connects on that port
3) Server creates a new socket (same address, different port number), tells the client to connect to that socket, and closes the connection with the client.
4) The client connects to the designated socket and provides the server with a channel it would like to be on
5) Server places that socket on the designated channel
6) Repeat steps 2 through 5 for each client that connects to the server
/* all of the above has been coded already */
7) Once a channel has 2 or more members, I'd like to have each member port be able to broadcast to all other ports in the same channel (and thus the clients communicate with each other)
In this situation, all involved sockets on the same channel have the same address and DIFFERENT port numbers. Everything I've read and researched about broadcasting and multicasting revolves around each communicator having the same port number and different addresses.
Is there a way to do the communication that I'm hoping to do, in C?
I would think you want to use the listen() and accept() functions for TCP. You can do what you describe and have clients talk to each other, but all traffic will run through the server as a hub.
If you want all clients to be able to talk to every other client, you have a few options:
Server is the hub for all data and passes it between clients for you
Clients maintain direct connections to the other clients and pass data to each other in order to facilitate the hub. This means lots of data copying.
Broadcast or multicast (UDP). This is only possible over a local network, as internet routers will block multicast and broadcast traffic.
I would probably go with #1.
Remember that each client has it's own IP address, so for a client to communicate with another client, and not involving the server, it would need to open a new connection with the other client, send data and then close the connection. While doable, I do not think this idea would scale very well.
I do agree with Syplex that having the server act as a relay hub is probably the best, and certainly has the potential to scale well. So the data-flow would be something like this:
a client receives a message that is to be retransmitted to all the other clients.
this message is passed to all other instances of your server process
each of these instances of your server process sends out the message.
The issue becomes how you are implementing you server, and you do have two models that fit what you describe:
(1) you are using a multi-treaded server, in which each new connection causes a thread to be spawned to handle the communication between the client and the server.
(2) you are using a forking server, in which the server forks a new process to communicate with the client.
In case (1) you would be interested in intra-process communication (message queue for example) while in case (2) you would be interested in inter-process communication (named pipes or shared memory for example).
At this point there are two many variables to give a concise answer. I hope this helps gets you started and at least gives you somewhere to start looking.

Binding 40 Sockets to 40 different IP addresses

I am writing on UDP server/client application.
I want my single server to handle 40 clients at a time. For this, I want to create 40 dedicated threads, each dedicated for one single client. Since there are 40 threads one for each client, I want to create 40 dedicated sockets as well.
But the problem that:
I don't know what will be the 40 IP addresses to which I shall bind() my sockets. (since as far as I now, I have to bind() to my Server\s IP address.) Normally I bind() to "INADDR_ANY" when there is only single socket.
But what should be the IP addresses at which I should bind() each of my 40 sockets?
Please help me. Any comment/ help is appreciated.
One common way to do this with UDP is:
Server bind() to a well known port.
Client sends the initial packet to that well known port
Server receive the first packet from a client on the well known port.
Server creates a new socket with a random port
Server replies to the client from this new socket.
Client receives the reply, notices it comes from another port than the well known
server port, and uses that port as the destination for further communication.
You'll use the getpeername() call to learn the remote address.
Keep in mind that UDP is connection-less, you'll need some way to signal the end or time out you sockets.
bind only needs the local address, not the remote address.
If you want one socket for each client, then you'll need to use different ports for each (using bind). That way, each client can send its traffic to a dedicated port, and you can have a thread for each socket/port.
It's probably a better idea to only have one socket (and one port) though, and have logic in your code to assign traffic to a thread based on the remote address (retrieved using recvfrom eg.).
The usual way is to bind a single socket and accept incoming connections. Each connection will be assigned a unique socket by accept.
As you are using UDP, I would simply use TCP as described above to let the clients know of their respective server UDP addresses.
Create a single listening socket in a dedicated listening thread.
When it receives a new packet, use the packet's remote addr/port, or put a unique clientID in the packet payload, to uniquely identify the client.
Create a new thread for that client if one does not already exist, pass the packet to that thread for further processing, and go back to listening.
If a given client thread does not receive any packets for awhile, it can terminate itself.

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?

Two-way communication in socket programming using C

I have a small doubt in socket programming. i am able to send my data from client to server and my server processes the data. The o/p of the data processed, I want to send back to my client. So can we "write" the data back to the client using the same socket. I mean a server listens on a port before accepting connection and receiving data, so similarly, do i need to make my client listen to some other port (bind it some other socket) and make my server connect to that socket and transfer the data back. Any kind of example or explanation or references would be appreciated. Thanks a lot in advance.
Check out Beej's Network Programming Guide first of all.
The basic screenplay of a server/client connection goes like this:
Server listen()s on a fixed port, with a given socket.
Client connect()s to a the server port; client obtains a socket.
Server accept()s the connection, and accept() returns a new socket for the connection.
(Server continues listening on the original port with the original socket.)
For the specific connection with the client, the server write()s to the new socket it obtained when accept()ing the incoming connection. A busy server will have many, many sockets, but it will only ever need to bind() to one port. All connections come in to that one port, but the OS's networking protocol stack separates the data and makes it available at the connection-specific socket.
You don't need a new socket.
A socket is a duplex connection you can send data in both directions and you can even close the socket from one direction (don't want to write anymore) but still send data from the other direction.
Your socket is bi-directional, so there is no need to create another socket. Unless you are using some sort of middleware, such as Pub/Sub, there is no need to create another socket to enable bi-directional communication.
Technically it is right, the socket is duplex and you can send the data to the same socket you read from:
SOCKET s = socket()
... //Connect
int size = receive(s,...);
//make response
send(s, ...);
But in practice it depends on what are you going to do. It is possible to hang out socket if you have the following situation:
Process 1 sends very big data (<100K) over the socket by one send
operation
Process 2 receives data from 1 by portions and sends small packets to 1 (~20b). It is not a
confirmations, but some external events.
The situation goes into hangout, where the sending buffer of the 2 is full and it stops sending confirmations to 1.
2 and 1 are hanging in their send operations making a deadlock.
In this case I'd recommend using two sockets. One for read, one for write.
(Late answer, so mainly for anyone else who comes here looking for help)
I recently put up an example client/server application that closely follows Beej's Guide to Network Programming (which was also recommended by Kerrek SB in his answer). If you're looking for a simple working example of client/server communication, maybe this will help:
https://github.com/countvajhula/dummyclientserver
In particular, no, your client does not need to set up a separate listening socket to receive data from the server -- after the server has accepted the connection from the client, the server can simply send data back to the client on the same socket.

Is it good to open multiple ports on TCP server?

The Tcp server need to serve many clients, If one client one server port and one server thread to listen the port, I want to know weather it is faster ?
If one port is good, could someone explain the different between one port and multiple ports in this case, thanks!
The problem with using multiple ports to achieve this is that each of your clients will each have a specific port number. Depending on the number of clients there could be a tremendous amount of bookkeeping involved.
Typically, for a tcp server that is to serve multiple clients, you have a "main" thread which listens to a port and accepts connections on that port. That thread then passes the connected socket off to another thread for processing and goes back to listening.
For a wealth of Unix network programming knowledge check out "The Stevens Book"
Generally speaking* the server will allocate it's own outgoing sockets for each connected client (and you don't need to be aware of those numbers). Each client connection handle will hold it's port references.
When defining the servers connection port, you will allocate a socket for incoming clients to connect to. There is no performance benefit using multiple sockets, in fact allocating additional sockets will show a performance hit (although for each port it will be tiny.)
update...
By the way, assigning multiple incoming ports (particularly a large range) for clients to connect to is also insane. From the perspective of making the service usable and maintainable.

Resources