Skip to main content

An Introduction to TCP Flags & C++ Demo(Server & Client)

My email: tcpfast@gmail.com 

If you are interested in my TCP software development, consulting or training services, please feel free to contact me.  



TCP flags are a set of six bits in the header of the Transmission Control Protocol (TCP), which is used to indicate or control the state or behavior of a TCP connection. TCP flags have the following types:

- SYN (Synchronization): Used to initiate a connection, establish a connection and set the initial sequence number.

- ACK (Acknowledgement): Used to acknowledge the received packets, or to respond to connection or disconnection requests.

- FIN (Finish): Used to request to terminate a connection, indicating that the sender has no more data to send.

- RST (Reset): Used to forcibly terminate a connection, indicating that the connection is abnormal or not accepted.

- URG (Urgent): Used to indicate that there is urgent data in the packet, which needs to be processed with priority.

- PSH (Push): Used to request to send data immediately, without waiting for the sender's buffer.


How TCP Flags Work

TCP flags are used to communicate the status and actions of a TCP connection between the sender and the receiver. For example, when a sender wants to establish a connection with a receiver, it sends a packet with the SYN flag set, indicating that it wants to synchronize the sequence number with the receiver. The receiver then responds with a packet with both the SYN and ACK flags set, indicating that it agrees to the connection and acknowledges the sender's packet. The sender then sends another packet with the ACK flag set, indicating that it acknowledges the receiver's packet. This process is called the **three-way handshake**, and it completes the connection establishment.


When a sender wants to terminate a connection with a receiver, it sends a packet with the FIN flag set, indicating that it has no more data to send. The receiver then responds with a packet with the ACK flag set, indicating that it acknowledges the sender's packet. The receiver then sends another packet with the FIN flag set, indicating that it also has no more data to send. The sender then responds with a packet with the ACK flag set, indicating that it acknowledges the receiver's packet. This process is called the **four-way handshake**, and it completes the connection termination.


When a sender or a receiver encounters an error or a problem with a connection, it sends a packet with the RST flag set, indicating that it wants to reset the connection. This packet does not require any acknowledgement, and it immediately terminates the connection.

When a sender has urgent data to send to a receiver, it sends a packet with the URG flag set, indicating that the packet contains urgent data. The packet also has a field called the **urgent pointer**, which specifies the offset of the urgent data from the beginning of the packet. The receiver then processes the urgent data with priority, and acknowledges the packet with the ACK flag set.

When a sender wants to send data to a receiver without waiting for its buffer to fill up, it sends a packet with the PSH flag set, indicating that it wants to push the data to the receiver. The receiver then receives the data and passes it to the application layer, and acknowledges the packet with the ACK flag set.


Why TCP Flags Are Important

TCP flags are important because they enable the reliable and orderly delivery of data over a TCP connection. TCP flags help to establish and terminate connections, to acknowledge and retransmit packets, to handle errors and problems, to prioritize urgent data, and to optimize data transmission. TCP flags are essential for the proper functioning of the TCP protocol, which is widely used for many applications on the Internet, such as web browsing, email, file transfer, and streaming. TCP flags are also useful for network analysis and troubleshooting, as they can reveal the state and behavior of a TCP connection. By examining the TCP flags in the packets, one can diagnose the performance and problems of a TCP connection, and take appropriate actions to improve or fix it.


C++ Demo Server

  1. // This is the server program
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/time.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #include <string.h>
  12. using namespace std;
  13. typedef struct TEMPIO
  14. {
  15.  unsigned int id;
  16.  unsigned short messageSender;
  17.  unsigned short length;
  18.  unsigned int secs;
  19.  unsigned int usecs;
  20.  unsigned short videoId;
  21.  unsigned short outChannel;
  22. }TEMPIO_msg;
  23. int client ();
  24. int server ();
  25. void error ();
  26. void error (const char *msg)
  27. {
  28.  perror (msg);
  29.  exit (0);
  30. }
  31. int main ()
  32. {
  33.  int sockfd, newsockfd, portno;
  34.  char * address;
  35.  socklen_t clilen;
  36.  struct sockaddr_in serv_addrcli_addr;
  37.  int n;
  38.  TEMPIO_msg message;
  39.  struct timeval time;
  40.  address="127.0.0.1";
  41.  portno = 2015// TBD
  42.  sockfd = socket (AF_INET, SOCK_STREAM, 0);
  43.  if (sockfd < 0) error ("ERROR opening socket");
  44.  bzero ( (char *) &serv_addr, sizeof (serv_addr));
  45.  serv_addr.sin_family = AF_INET;
  46.  serv_addr.sin_addr.s_addr = INADDR_ANY;
  47.  serv_addr.sin_port = htons (portno);
  48.  if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) error ("ERROR on binding");
  49.  listen (sockfd,5);
  50.  clilen = sizeof (cli_addr);
  51.  printf ("SRV: started! \n");
  52.  newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
  53.  if (newsockfd < 0) error ("ERROR on accept");
  54.  printf ("SRV: client connected! \n"); // This will complete the three-way handshake with the client, and set the SYN and ACK flags accordingly
  55.  printf ("SRV: Listening... ");
  56.  if (recvfrom (sockfd,&message,sizeof (TEMPIO_msg),MSG_PEEK, (struct sockaddr *) &cli_addr, &clilen) > 0) {
  57.   printf ("SRV catched something!\n");
  58.  }
  59.  close (newsockfd);
  60.  close (sockfd);
  61.  return 0;
  62. }


C++ Demo Client:

  1. // This is the client program
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <sys/time.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #include <string.h>
  12. using namespace std;
  13. typedef struct TEMPIO
  14. {
  15.  unsigned int id;
  16.  unsigned short messageSender;
  17.  unsigned short length;
  18.  unsigned int secs;
  19.  unsigned int usecs;
  20.  unsigned short videoId;
  21.  unsigned short outChannel;
  22. }TEMPIO_msg;
  23. int client ();
  24. int server ();
  25. void error ();
  26. void error (const char *msg)
  27. {
  28.  perror (msg);
  29.  exit (0);
  30. }
  31. int main ()
  32. {
  33.  int sockfd, portno, n;
  34.  char * address;
  35.  struct sockaddr_in serv_addr;
  36.  struct hostent *server;
  37.  TEMPIO_msg message;
  38.  struct timeval time;
  39.  portno=2015;//TBD take portno
  40.  address="127.0.0.1";//TBD take address
  41.  message.id=htonl (1694367746);
  42.  message.messageSender=htons (100);
  43.  message.length=htons (20);
  44.  gettimeofday (&time,NULL);
  45.  message.secs=htonl (time.tv_sec);
  46.  message.usecs=htonl (time.tv_usec);
  47.  message.videoId=htons (44);
  48.  message.outChannel=htons (38);
  49.  sockfd = socket (AF_INET, SOCK_STREAM, 0);
  50.  if (sockfd < 0) {
  51.   error ("ERROR opening socket");
  52.   exit (0);
  53.  }
  54.  server = gethostbyname (address);
  55.  if (server == NULL) {
  56.   fprintf (stderr,"ERROR, no such host\n");
  57.   exit (0);
  58.  }
  59.  bzero ( (char *) &serv_addr, sizeof (serv_addr));
  60.  serv_addr.sin_family = AF_INET;
  61.  bcopy ( (char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,server->h_length);
  62.  serv_addr.sin_port = htons (portno);
  63.  if (connect (sockfd, (struct sockaddr *) &serv_addr,sizeof (serv_addr)) < 0) {
  64.   error ("ERROR connecting"); // This will initiate the three-way handshake with the server, and set the SYN and ACK flags accordingly
  65.   exit (0);
  66.  }
  67.  while (true) {
  68.   if (sendto (sockfd,&message,sizeof (TEMPIO_msg),MSG_EOR, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
  69.    perror ("sendto");
  70.    exit (1);
  71.   }else {
  72.    printf ("CLI: sent something...\n");
  73.   }
  74.   sleep (3);
  75.  }
  76.  close (sockfd);
  77.  return 0;
  78. }


email: tcpfast@gmail.com  

free contact to me, :)






Comments

Popular posts from this blog

How to Fix TCP Socket Error Code 10061 in C++, Python, and Java

If you are interested in my TCP socket software development, consulting or training services, please feel free to contact me.   contact email: tcpfast@gmail.com TCP  socket error code 10061 is a common network connection error that indicates that the target server refused the connection request. This usually happens when you try to connect to a service that is not running on the target host, or when your network firewall or antivirus software blocks the port communication. In this blog post, I will explain the possible causes of this error and how to fix it in different programming languages, such as C++, Python, and Java. Possible Causes of TCP Socket Error Code 10061 There are several possible reasons why you may encounter TCP error code 10061 when you try to establish a TCP connection with a server. Some of the most common ones are: - You are using the wrong port number or protocol type (TCP or UDP) to connect to the server. For example, if the server is listening on p...

How to Set Buffer Size for TCP Socket Programming in C++

TCP socket programming is a common way to communicate between different processes or machines over the network. However, one of the challenges of TCP socket programming is how to set the buffer size for sending and receiving data. The buffer size determines how much data can be stored in memory before it is transmitted or processed. If the buffer size is too small, the data may be fragmented or lost, resulting in poor performance or errors. If the buffer size is too large, the memory may be wasted or the data may be delayed, affecting the responsiveness or timeliness of the communication. In this blog post, I will explain how to set the buffer size for TCP socket programming in C++, and provide some examples of how to use the relevant functions and parameters. The buffer size for TCP socket programming in C++ can be set by using the setsockopt function, which allows the programmer to change the options for a socket. The setsockopt function has the following prototype: int setsockopt...

How to enable and configure root user’s SSH login on Azure Ubuntu

If you are using Microsoft’s Azure Ubuntu, you may find that the default normal user azureuser has some limitations, such as not being able to use ports below 1024 when setting up SSH Server2Client (S2C) port mapping. At this time, you may want to use the root user to gain higher privileges and flexibility. However, Azure Ubuntu does not directly support root user login, you need to do some configuration to achieve it. This article will introduce how to enable and configure root user’s SSH login on Azure Ubuntu, and how to use root user’s SSH public key login method. Enable root user’s password login First, we need to set a password for the root user, and then modify some configuration files to allow root user’s password login. The specific steps are as follows: Log in to the system as a normal user azureuser, open the terminal, and enter the following command to set a password for the root user: sudo passwd root Enter your azureuser password, then enter the root password you want to s...