In this blog post, I will show you how to write a simple TCP socket server echo program in VC++. A TCP socket server echo program is a program that listens on a specific port, accepts connections from clients, and echoes back any data received from the clients. This is a useful way to test the basic functionality of TCP sockets and learn how to use the Winsock API in VC++.
If you are interested in my TCP software development, consulting or training services, please feel free to contact me.
contact email: tcpfast@gmail.com
What is a TCP Socket?
A TCP socket is a communication endpoint that uses the Transmission Control Protocol (TCP) to exchange data reliably and orderly over a network. TCP is one of the core protocols of the Internet Protocol Suite, and it provides reliable, ordered, and error-checked delivery of data between applications running on different machines.
A TCP socket is defined by the IP address of the machine and the port number it uses. The IP address is a unique identifier of the machine on the network, and the port number is a 16-bit number that identifies the specific application or service on the machine. For example, the well-known port number for HTTP is 80, and the well-known port number for FTP is 21.
A TCP socket can be either a server socket or a client socket. A server socket is a socket that listens for incoming connections from client sockets. A client socket is a socket that initiates a connection to a server socket. A TCP connection is established when a client socket and a server socket agree to communicate with each other. A TCP connection is identified by a four-tuple: the IP address and port number of the client socket, and the IP address and port number of the server socket.
How to Write a TCP Socket Server Echo Program in VC++
To write a TCP socket server echo program in VC++, we need to use the Winsock API, which is a set of functions and data structures that provide access to the Windows Sockets implementation. The Winsock API is based on the Berkeley Sockets API, which is a standard interface for network programming in Unix-like systems.
The basic steps to write a TCP socket server echo program in VC++ are:
- Initialize the Winsock library using the `WSAStartup` function.
- Create a TCP server socket using the `socket` function.
- Bind the server socket to a specific port number using the `bind` function.
- Listen for incoming connections using the `listen` function.
- Accept a client connection using the `accept` function.
- Receive data from the client using the `recv` function.
- Echo the data back to the client using the `send` function.
- Close the client socket using the `closesocket` function.
- Repeat steps 5 to 8 for each client connection.
- Close the server socket using the `closesocket` function.
- Clean up the Winsock library using the `WSACleanup` function.
The following is the complete code of the TCP socket server echo program in VC++, with some comments to explain the functionality:
- // EchoServer.cpp : Defines the entry point for the console application.
- //
- // A function to print the error message and exit the program
- void error(const char* msg)
- {
- std::cerr << msg << ": " << WSAGetLastError() << std::endl; // Print the error code
- exit(1); // Terminate the program
- }
- // A function to handle the client connection
- DWORD WINAPI clientHandler(LPVOID lpParam)
- {
- SOCKET clientSock = (SOCKET)lpParam; // Cast the parameter to SOCKET
- char buffer[BUFFER_SIZE]; // A buffer to store the data
- int recvSize; // The number of bytes received
- std::string data; // The data received
- std::string echo; // The data to be echoed back
- while (true)
- {
- // Receive data from the client
- recvSize = recv(clientSock, buffer, BUFFER_SIZE, 0);
- // Check if the connection is closed or an error occurred
- if (recvSize == 0 || recvSize == SOCKET_ERROR)
- {
- std::cout << "Client disconnected." << std::endl;
- closesocket(clientSock); // Close the socket
- return 0; // Exit the thread
- }
- // Convert the buffer to a string object
- data = std::string(buffer, recvSize);
- // Prepend "server echo:" to the data
- echo = "server echo:" + data;
- // Send the data back to the client
- send(clientSock, echo.c_str(), echo.length(), 0);
- }
- return 0; // Exit the thread
- }
- int main(int argc, char* argv[])
- {
- // Initialize the Winsock library
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- error("Failed to initialize Winsock");
- }
- // Create a TCP server socket
- SOCKET serverSock = socket(AF_INET, SOCK_STREAM, 0);
- if (serverSock == INVALID_SOCKET)
- {
- error("Failed to create socket");
- }
- // Construct the server address structure
- sockaddr_in serverAddr;
- serverAddr.sin_family = AF_INET; // Internet address family
- serverAddr.sin_addr.s_addr = INADDR_ANY; // Any incoming interface
- serverAddr.sin_port = htons(ECHO_PORT); // Echo server port
- // Bind the socket to the server address
- if (bind(serverSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
- {
- error("Failed to bind the socket");
- }
- // Listen for incoming connections
- if (listen(serverSock, MAX_CLIENTS) == SOCKET_ERROR)
- {
- error("Failed to listen on the socket");
- }
- std::cout << "Echo server is running on port " << ECHO_PORT << std::endl;
- // Accept the client connections
- SOCKET clientSock; // The accepted client socket
- sockaddr_in clientAddr; // The address of the client
- int clientLen = sizeof(clientAddr); // The length of the address
- HANDLE clientThread; // The handle of the thread for the client
- while (true)
- {
- // Accept a client connection
- clientSock = accept(serverSock, (sockaddr*)&clientAddr, &clientLen);
- if (clientSock == INVALID_SOCKET)
- {
- error("Failed to accept a client connection");
- }
- std::cout << "Client connected: " << inet_ntoa(clientAddr.sin_addr) << std::endl;
- // Create a new thread to handle the client connection
- clientThread = CreateThread(NULL, 0, clientHandler, (LPVOID)clientSock, 0, NULL);
- if (clientThread == NULL)
- {
- error("Failed to create a thread for the client");
- }
- }
- // Close the server socket
- closesocket(serverSock);
- // Clean up the Winsock library
- WSACleanup();
- return 0;
- }
How to Test the TCP Socket Server Echo Program in VC++
To test the TCP socket server echo program in VC++, we need to compile and run the program, and then use a TCP client program to connect to the server and send data. One simple way to do this is to use the `telnet` command, which is a terminal emulator that can communicate with TCP servers.
You can compile this C++ program in an IDE (Integrated Development Environment) or use the cl.exe command to compile it on the console. Taking VS2019 as an example, cl.exe is located in:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\bin\Hostx86\x86\cl.exe"
It is recommended to use IDE to generate exe
The following steps show how to test the TCP socket server echo program in VC++ using the `telnet` command:
- Open a command prompt and navigate to the folder where the EchoServer.cpp file is located.
- Compile the program using the following command: `cl EchoServer.cpp ws2_32.lib`
- Run the program using the following command: `EchoServer`
- Open another command prompt and use the `telnet` command to connect to the server on port 4444: `telnet localhost 4444`
- Type any data and press enter. The server should echo back the same data with "server echo:" prepended to it.
- To close the connection, type `Ctrl+]` and then `quit`.
The following is an example of the output of the test:
- C:\Users\tcpBuilder\Desktop>cl EchoServer.cpp ws2_32.lib
- Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
- Copyright (C) Microsoft Corporation. All rights reserved.
- EchoServer.cpp
- Microsoft (R) Incremental Linker Version 14.00.24215.1
- Copyright (C) Microsoft Corporation. All rights reserved.
- EchoServer.exe :
- EchoServer.obj
- ws2_32.lib
- C:\Users\tcpBuilder\Desktop>EchoServer
- Echo server is running on port 4444
- C:\Users\tcpBuilder\Desktop>telnet localhost 4444
- Connecting To localhost...Could not open connection to the host, on port 4444: Connect failed
- Hello
- server echo:Hello
- World
- server echo:World
- Ctrl+]
- quit
- Connection to host lost.
- C:\Users\tcpBuilder\Desktop>
If you have any questions or feedback, please feel free email to me (tcpfast@gmail.com) or leave a comment below.
Thank you for reading.
Comments
Post a Comment