TCP Client Data Sending Code in C Language with Detailed Comments

🎯 Core Functionality

Send a string of data to a specified IP and port using the TCP protocol, including a timestamp and CRC check.

1. TCP Client Communication

  • Establish a TCP connection with the specified server

  • Continuously send structured data packets

  • Support automatic reconnection mechanism

  • Regularly send heartbeat packets to keep the connection alive

2. Data Packet Format

Each data packet contains the following information:

BATCH:123|TIME:14:30:25.456|DATA:1,2,3,4,5,6,7,8,9,10|CRC:3A7B
  • Batch Number:Sequentially increasing number

  • Timestamp:Sending time accurate to milliseconds

  • Data Content:Sequence of numbers from 1 to 10

  • CRC Check:Data integrity verification (CRC16 algorithm)

TCP Client Data Sending Code in C Language with Detailed Comments

🎯 Complete Code and Comments

#define _WINSOCK_DEPRECATED_NO_WARNINGS  // Disable deprecated API warnings#define _CRT_SECURE_NO_WARNINGS          // Disable security warnings
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#include <windows.h>#include <signal.h>#include <conio.h>  // Include conio.h for _kbhit and _getch
#pragma comment(lib, "ws2_32.lib")  // Link Winsock library
// ========== Configurable Macros ==========#define DEFAULT_SERVER_IP "127.0.0.1"      // Default server IP address (localhost)#define DEFAULT_SERVER_PORT 8080           // Default server port number#define PACKET_COUNT 100                    // Number of packets to send each time (1-10)#define SEND_INTERVAL_MS 50              // Sending interval (milliseconds)#define RECONNECT_INTERVAL_MS 10          // Reconnect attempt interval (milliseconds)#define HEARTBEAT_INTERVAL_MS 300        // Heartbeat packet sending interval (milliseconds)#define BUFFER_SIZE 1024                   // Data buffer size// ==================================
volatile sig_atomic_t keepRunning = 1;     // Program running control flag
/*** @brief Signal handler function for handling Ctrl+C signal* @param signal Signal code */void signalHandler(int signal) {if (signal == SIGINT)  {printf("\nReceived termination signal, exiting...\n");        keepRunning = 0;  // Set running flag to false    }}
/*** @brief CRC16 checksum calculation function* @param data Pointer to the data to be checked* @param length Length of the data* @return CRC16 checksum value*/unsigned short calculateCRC16(const unsigned char* data, size_t length) {unsigned short crc = 0xFFFF;  // Initial CRC value
                                  // Iterate through each byte in the datafor (size_t i = 0; i < length; i++)  {        crc ^= (unsigned short)data[i] << 8;  // Shift byte to high and XOR with CRC
                                              // Process each bit of the bytefor (int j = 0; j < 8; j++)     {if (crc & 0x8000)           {  // Check if the highest bit is 1                crc = (crc << 1) ^ 0x1021;  // Shift left and XOR with polynomial            }else           {                crc <<= 1;  // Just shift left            }        }    }return crc;  // Return the calculated CRC value}
/*** @brief Get current time string* @param buffer Buffer to store the time string* @param bufferSize Size of the buffer*/void getCurrentTimeString(char* buffer, size_t bufferSize) {    SYSTEMTIME systemTime;           // System time structureGetLocalTime(&systemTime);       // Get local time
// Format as string: hour:minute:second.millisecondsprintf(buffer, "%02d:%02d:%02d.%03d",        systemTime.wHour,    // Hour        systemTime.wMinute,  // Minute        systemTime.wSecond,  // Second        systemTime.wMilliseconds);  // Milliseconds}
/*** @brief Establish TCP connection* @param ip Server IP address* @param port Server port number* @return Returns socket on success, INVALID_SOCKET on failure*/SOCKET establishConnection(const char* ip, int port) {    SOCKET sock = INVALID_SOCKET;  // Rename variable to avoid conflict with function namestruct sockaddr_in serverAddr;
// Create TCP socket - use variable name sock instead of socket    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sock == INVALID_SOCKET)  {printf("Failed to create socket: %ld\n", WSAGetLastError());return INVALID_SOCKET;    }
// Set send timeout option (5 seconds)int timeout = 5000;setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));// Set receive timeout option (5 seconds)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
// Set address reuse option for quick reconnectionint reuse = 1;setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
// Configure server address information    serverAddr.sin_family = AF_INET;           // IPv4 address family    serverAddr.sin_port = htons(port);         // Port number (host byte order to network byte order)    serverAddr.sin_addr.s_addr = inet_addr(ip); // IP address conversion
// Attempt to connect to serverif (connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)  {printf("Failed to connect to server: %ld\n", WSAGetLastError());closesocket(sock);  // Close socketreturn INVALID_SOCKET;    }
return sock;  // Return successful socket}
/*** @brief Send heartbeat packet to keep connection alive* @param socket Connected socket* @return Returns number of bytes sent on success, SOCKET_ERROR on failure*/int sendHeartbeat(SOCKET sock) {const char* heartbeat = "HEARTBEAT";  // Heartbeat packet contentreturn send(sock, heartbeat, (int)strlen(heartbeat), 0);  // Send heartbeat packet}
/*** @brief Main function* @return Program exit code*/int main() {    WSADATA wsaData;                  // Winsock initialization data    SOCKET clientSocket = INVALID_SOCKET;  // Client socketchar packetData[BUFFER_SIZE];     // Data packet bufferchar timeStr[32];                 // Time string bufferint iResult;                      // Function call resultint batchCount = 0;               // Sending batch counter    DWORD lastSendTime = 0;           // Last send time    DWORD lastHeartbeatTime = 0;      // Last heartbeat timeint connectionAttempts = 0;       // Connection attempt count
                                      // Register Ctrl+C signal handlersignal(SIGINT, signalHandler);
// Display program informationprintf("TCP Client - Continuously sending data (configurable interval)\n");printf("Server: %s:%d\n", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT);printf("Sending interval: %d milliseconds\n", SEND_INTERVAL_MS);printf("Number of data sent each time: %d\n", PACKET_COUNT);printf("Press Ctrl+C to terminate the program\n");printf("==================================================\n");
// Initialize Winsock library    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0)  {printf("WSAStartup failed: %d\n", iResult);return 1;  // Initialization failed, exit program    }
// Main loop - keep program running until termination signal is receivedwhile (keepRunning)  {    // Check if connection needs to be establishedif (clientSocket == INVALID_SOCKET)     {            connectionAttempts++;  // Increase connection attempt countprintf("Attempting to connect to server (Attempt %d)...\n", connectionAttempts);
// Attempt to establish connection            clientSocket = establishConnection(DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT);if (clientSocket == INVALID_SOCKET)            {Sleep(RECONNECT_INTERVAL_MS);  // Wait and retrycontinue;            }
printf("Successfully connected to server\n");  // Remove ✓ symbol to avoid encoding issues            connectionAttempts = 0;  // Reset connection attempt counter
                                         // Set timestamp to send data immediately in the next loop            lastSendTime = GetTickCount() - SEND_INTERVAL_MS;            lastHeartbeatTime = GetTickCount();  // Record heartbeat time        }
        DWORD currentTime = GetTickCount();  // Get current time
                                                // Check if heartbeat packet needs to be sentif (currentTime - lastHeartbeatTime >= HEARTBEAT_INTERVAL_MS)     {        // Send heartbeat packet to check connection statusif (sendHeartbeat(clientSocket) == SOCKET_ERROR)            {printf("Heartbeat packet sending failed, connection may be lost\n");closesocket(clientSocket);                clientSocket = INVALID_SOCKET;  // Mark for reconnectioncontinue;            }            lastHeartbeatTime = currentTime;  // Update heartbeat timeprintf("Heartbeat packet sent\n");  // Remove ✓ symbol        }
// Check if sending interval time has been reachedif (currentTime - lastSendTime >= SEND_INTERVAL_MS)     {            lastSendTime = currentTime;  // Update last send time            batchCount++;                // Increase batch counter
                                         // Get current time stringgetCurrentTimeString(timeStr, sizeof(timeStr));
// Construct data packetint offset = 0;// Add header information: batch number and timestamp            offset += sprintf(packetData, "BATCH:%d|TIME:%s|DATA:", batchCount, timeStr);
// Add data content: 1 to PACKET_COUNTfor (int i = 1; i <= PACKET_COUNT; i++)            {                offset += sprintf(packetData + offset, "%d", i);// Add comma separator between numbers (not added for the last one)if (i < PACKET_COUNT)                {                    offset += sprintf(packetData + offset, ",");                }            }
// Calculate CRC check (for timestamp and data part)const char* crcData = strstr(packetData, "TIME:") + 5;  // Skip "TIME:" prefixunsigned short crc = calculateCRC16((const unsigned char*)crcData, (unsigned int)strlen(crcData));
// Add CRC check information            offset += sprintf(packetData + offset, "|CRC:%04X", crc);
// Send data to server            iResult = send(clientSocket, packetData, offset, 0);if (iResult == SOCKET_ERROR)            {int error = WSAGetLastError();  // Get error codeprintf("Sending failed (Error: %d), reconnecting...\n", error);closesocket(clientSocket);                clientSocket = INVALID_SOCKET;  // Mark for reconnection            }else            {// Display success messageprintf("[%04d] %s | Data:1-%d | CRC:%04X | Interval:%dms\n",                    batchCount, timeStr, PACKET_COUNT, crc, SEND_INTERVAL_MS);            }        }
// Check connection status (non-blocking mode)if (clientSocket != INVALID_SOCKET)     {char testBuffer[1];  // Test buffer                                    // Use MSG_PEEK mode to check connection status (does not actually receive data)if (recv(clientSocket, testBuffer, 1, MSG_PEEK) == SOCKET_ERROR)            {int error = WSAGetLastError();// If not "operation would block" error, connection has issuesif (error != WSAEWOULDBLOCK)                {printf("Connection check failed, reconnecting...\n");closesocket(clientSocket);                    clientSocket = INVALID_SOCKET;  // Mark for reconnection                }            }        }
Sleep(10);  // Short sleep to avoid high CPU usage    }
// Cleanup before program exitif (clientSocket != INVALID_SOCKET)     {printf("Closing connection...\n");closesocket(clientSocket);  // Close socket    }
WSACleanup();  // Clean up Winsock resources
                   // Display program run statisticsprintf("\nProgram has ended\n");printf("Total batches sent: %d\n", batchCount);printf("Press any key to exit...\n");
// Clear input buffer - use standard functionwhile (_kbhit()) _getch();getchar();  // Wait for user key press
}

TCP Client Data Sending Code in C Language with Detailed Comments

🎯 Code Verification

Auxiliary Tool: Network Debugging Assistant Use the Network Debugging Assistant to receivedata sent by the TCP client.Settings:1)❌ Do not manually configure the IP address on the local computer! (127.0.0.1 is the loopback address, automatically supported by all computers)2)Simply set the following content on the Network Debugging Assistant:TCP Client Data Sending Code in C Language with Detailed CommentsLoopback Address 127.0.0.1 is a specialIPv4 address, known as the “loopback address”, which always points tothe local machine. The loopback address 127.0.0.1 is automatically supported by all computers. The IPv4 standard specifies127.0.0.0/8as the loopback network segment After setting up the Network Debugging Assistant, startthe debugging assistant and run the code.TCP Client Data Sending Code in C Language with Detailed CommentsTCP Client Data Sending Code in C Language with Detailed CommentsTCP Client Data Sending Code in C Language with Detailed Comments “ Your support is my greatest motivation ”

Leave a Comment