I have written a basic client server code to understand the TCP states. Client code :
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(){
int clientSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
socklen_t addr_size;
/*---- Create the socket. The three arguments are: ----*/
/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
clientSocket = socket(PF_INET, SOCK_STREAM, 0);
/*---- Configure settings of the server address struct ----*/
/* Address family = Internet */
serverAddr.sin_family = AF_INET;
/* Set port number, using htons function to use proper byte order */
serverAddr.sin_port = htons(7891);
/* Set IP address to localhost */
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
/* Set all bits of the padding field to 0 */
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*---- Connect the socket to the server using the address struct ----*/
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
/*---- Read the message from the server into the buffer ----*/
recv(clientSocket, buffer, 1024, 0);
/*---- Print the received message ----*/
printf("Data received: %s",buffer);
return 0;
}
Server Code :
/****************** SERVER CODE ****************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(){
int welcomeSocket, newSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(7891);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if(listen(welcomeSocket,5)==0)
printf("Listening\n");
else
printf("Error\n");
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
strcpy(buffer,"Hello World\n");
send(newSocket,buffer,13,0);
return 0;
}
I am running the command netstat -an | grep 7891
, so at various points of time, I am getting the states ESTABLISHED, LISTENING, FINWAIT2, CLOSE_WAIT and TIME_WAIT.
How to get the other states like SYN_RECV, SYN_SENT, FINWAIT1, CLOSING and LAST ACK.
I have tried with various netstat options and ss options but to no vain.
To Displays all active TCP connections and the TCP and UDP ports on which the computer is listening type the following command: netstat -a To displays active TCP connections and includes the process ID (PID) for each connection type the following command: netstat -o To display both the Ethernet statistics and the ...
The states are: LISTEN, SYN-SENT, SYN- RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, and the fictional state CLOSED.
The Work with TCP/IP Network Status (WRKTCPSTS) command, also known as NETSTAT, is used to get information about the status of TCP/IP network routes, interfaces, TCP connections and UDP ports on your local system. You can also use NETSTAT to end TCP/IP connections and to start or end TCP/IP interfaces.
A TCP socket is a specific TCP port on a specific node. Port exhaustion occurs when a node runs out of available ports. When an application stops using a specific port, the port enters a "time-wait state" before it becomes available for use by another application.
You do not see SYN_RECV
, SYN_SENT
and other, because these stages are too short. For example, when after succesfull accept()
on server side you have got ESTABLISHED, all previous states would be performed rapidly by TCP stack.
So, you are watching only long states of tcp connections.
You can achieve SYN_* states by simulating SYN-flood: use backlog parameter for listen(...,1)
at server side and sleep before return 0
. And try to launch several separate clients. As result you will get: 1 in ETSABLISHED
and several in SYN_* states.
About finalize states. You should call shutdown()
and close()
and set sleep between them too. I recommend you to use fork()
to make child process and use synchronizations primitives to understand TCP states
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With