TCP Client/Server (Basic) - Sample Code
This section provides the source code for a basic TCP client and server application. This sample demonstrates fundamental concepts of network communication using TCP sockets in a Windows environment.
Client Code
C#
C++
Program.cs (Client)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class TcpClientExample
{
public static void Main(string[] args)
{
try
{
// Define server IP address and port
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
int port = 11000;
TcpClient client = new TcpClient();
Console.WriteLine($"Connecting to server at {ipAddress}:{port}...");
client.Connect(ipAddress, port);
Console.WriteLine("Connected to server.");
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
// Send message to server
string messageToSend = "Hello from TCP Client!";
byte[] data = Encoding.ASCII.GetBytes(messageToSend);
stream.Write(data, 0, data.Length);
Console.WriteLine($"Sent: {messageToSend}");
// Receive response from server
byte[] buffer = new byte[256];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string responseData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine($"Received: {responseData}");
// Close everything
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Console.WriteLine($"ArgumentNullException: {e}");
}
catch (SocketException e)
{
Console.WriteLine($"SocketException: {e}");
}
finally
{
Console.WriteLine("Client finished.");
}
}
}
client.cpp
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
SOCKET clientSocket = INVALID_SOCKET;
struct sockaddr_in serverAddr;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cerr << "WSAStartup failed: " << iResult << std::endl;
return 1;
}
// Create a SOCKET for connecting to server
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Error at socket(): " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
// Setup the server address structure
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(11000); // Server port
inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr); // Server IP address
// Connect to server.
iResult = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
std::cerr << "connect failed with error: " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "Connected to server." << std::endl;
// Send an initial buffer
std::string messageToSend = "Hello from TCP Client!";
iResult = send(clientSocket, messageToSend.c_str(), (int)messageToSend.length(), 0);
if (iResult == SOCKET_ERROR) {
std::cerr << "send failed with error: " << WSAGetLastError() << std::endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
std::cout << "Sent: " << messageToSend << std::endl;
char recvbuf[512];
int recvbuflen = 512;
// Receive until the peer closes the connection
iResult = recv(clientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
std::cout << "Received: " << std::string(recvbuf, 0, iResult) << std::endl;
} else if (iResult == 0) {
std::cout << "Connection closing..." << std::endl;
} else {
std::cerr << "recv failed with error: " << WSAGetLastError() << std::endl;
}
// Cleanup
closesocket(clientSocket);
WSACleanup();
std::cout << "Client finished." << std::endl;
return 0;
}
Server Code
C#
C++
Program.cs (Server)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class TcpServerExample
{
private TcpListener server;
private bool isServerRunning = true;
public TcpServerExample(int port)
{
IPAddress localAddr = IPAddress.Any;
server = new TcpListener(localAddr, port);
}
public void Start()
{
try
{
server.Start();
Console.WriteLine($"Server started. Listening on port {((IPEndPoint)server.LocalEndpoint).Port}...");
while (isServerRunning)
{
Console.WriteLine("Waiting for a connection...");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Client connected!");
// Handle client connection in a separate thread
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
catch (SocketException e)
{
Console.WriteLine($"SocketException: {e}");
}
finally
{
server.Stop();
Console.WriteLine("Server stopped.");
}
}
public void Stop()
{
isServerRunning = false;
if (server != null)
{
server.Stop();
}
}
private void HandleClientComm(object clientObj)
{
TcpClient tcpClient = (TcpClient)clientObj;
NetworkStream stream = null;
try
{
stream = tcpClient.GetStream();
byte[] buffer = new byte[1024];
int bytesRead;
// Read incoming data
bytesRead = stream.Read(buffer, 0, buffer.Length);
string data = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine($"Received from client: {data}");
// Send response back to client
string responseMessage = "Message received by server!";
byte[] responseData = Encoding.ASCII.GetBytes(responseMessage);
stream.Write(responseData, 0, responseData.Length);
Console.WriteLine($"Sent to client: {responseMessage}");
}
catch (Exception e)
{
Console.WriteLine($"Error handling client: {e.Message}");
}
finally
{
stream?.Close();
tcpClient?.Close();
Console.WriteLine("Client connection closed.");
}
}
public static void Main(string[] args)
{
int port = 11000;
TcpServerExample server = new TcpServerExample(port);
server.Start();
}
}
server.cpp
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#include <vector>
#include <process.h> // For _beginthreadex
#pragma comment(lib, "ws2_32.lib")
// Thread function for handling client connections
unsigned __stdcall ClientHandler(void* pParam)
{
SOCKET clientSocket = (SOCKET)pParam;
char buffer[512];
int bytesReceived;
std::cout << "Client connected. Waiting for data..." << std::endl;
// Receive data from client
bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
if (bytesReceived > 0) {
buffer[bytesReceived] = '\0'; // Null-terminate the received data
std::string receivedData(buffer);
std::cout << "Received: " << receivedData << std::endl;
// Send response back to client
std::string responseMessage = "Message received by server!";
send(clientSocket, responseMessage.c_str(), (int)responseMessage.length(), 0);
std::cout << "Sent: " << responseMessage << std::endl;
} else if (bytesReceived == 0) {
std::cout << "Client disconnected gracefully." << std::endl;
} else {
std::cerr << "recv failed with error: " << WSAGetLastError() << std::endl;
}
// Cleanup the client socket
closesocket(clientSocket);
std::cout << "Client connection closed." << std::endl;
_endthreadex(0);
return 0;
}
int main()
{
WSADATA wsaData;
SOCKET listenSocket = INVALID_SOCKET;
struct sockaddr_in serverAddr;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cerr << "WSAStartup failed: " << iResult << std::endl;
return 1;
}
// Create a SOCKET for the server to listen on
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenSocket == INVALID_SOCKET) {
std::cerr << "Error at socket(): " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
// Setup the server structure
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY; // Listen on any interface
serverAddr.sin_port = htons(11000); // Port to listen on
// Bind the socket
iResult = bind(listenSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
std::cerr << "bind failed with error: " << WSAGetLastError() << std::endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
// Listen on the socket
if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
std::cerr << "listen failed with error: " << WSAGetLastError() << std::endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
std::cout << "Server started. Listening on port 11000..." << std::endl;
SOCKET clientSocket;
while (true) {
std::cout << "Waiting for a connection..." << std::endl;
// Accept a client socket
clientSocket = accept(listenSocket, NULL, NULL);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "accept failed with error: " << WSAGetLastError() << std::endl;
// Optionally break or continue based on error severity
continue;
}
// Create a new thread to handle the client
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientHandler, (void*)clientSocket, 0, &threadID);
if (hThread == 0) {
std::cerr << "Failed to create client handling thread. Error: " << GetLastError() << std::endl;
closesocket(clientSocket); // Close the client socket if thread creation fails
} else {
CloseHandle(hThread); // Close the thread handle to release resources
}
}
// No explicit cleanup for listenSocket here as the loop is infinite for a typical server.
// In a real application, you would have a mechanism to gracefully shut down the server.
// closesocket(listenSocket);
// WSACleanup();
// return 0;
}