Two-way communication in socket programming using C - 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.

Related

Will a disconnected udp socket still receive traffic from a port that another socket is connected to?

I'm trying to write a server/client pair to run over udp, and the only way i've been able to get it going is having the server aware of the client's ip and port before the connection starts. My new design involves waiting for a packet to come in, recording the sender address, forking to a child process (the parent loops around and continues listening), which then connect's to the client the transmitted the packet. The child should then only receive packets from the associated client, but the documentation is unclear is the parent socket will continue receive traffic from that client. I'm working on a program to try it, but i figured i could ask the question at the same time.
EDIT: It seems that when the child's socket is connected'd it will connect the parent's socket too.
UDP protocol does not operate connections, it's a connection-less protocol. It is enough for one side to listen and other side to just send datagrams for data channel to work.
On the question (sorry, didn't got the point before): forking is not the way out when working with UDP. Connection-based protocols are widely used with that technique. That is possible because:
you can fork right after listen()
the first process accepts connection works with it (and only that process posesses the newly created connected socket.
When you work with UDP you don't have such gap (as before accept() with TCP) to know when exactly to fork (especially when you have intensive datagram flow).
So, when you design UDP service, you need either
use non-blocking I/O with event loop or
design threaded solution.

In C, how to periodically send UDP datagram to multiple peers (possibly thousands)?

(I'm new to network programming, and I am working on C in Linux)
I followed Beej's guide for a simple UDP listener-talker and I know how to create a socket and send that to a destination (with calls to getaddrinfo() and socket() using SOCK_DGRAM)
See http://beej.us/guide/bgnet/output/html/multipage/clientserver.html#datagram.
In my distributed app, I will need to send a message to multiple peers (reliable multicast).
My question is: do I need to create a socket for each of the peers? I'm worried about scalability. Or should I create the socket, use it and destroy it (close it) after each message?
In summary, is there a good way to send a UDP packet to multiple destinations, periodically?
Thanks for the help!
For UDP, you need but one local socket. You can send a packet to any destination you like from that one, single socket.
Also, you don't need to destroy and recreate the socket after each message. Just keep the socket open, and keep sending messages.

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?

Passing control information between client-server in socket programming in 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.

Resources