WRITING A C++ SERVER AND CLIENT SOCKET
Setting Up the Server
Step 1: Initialize Winsock
In the server, the first step is to initialize the Winsock library. This involves loading the DLL and setting up the necessary variables. The following code demonstrates how to achieve this:
#include <iostream> #include <winsock2.h> int main() { // Initialize WSA variables WSADATA wsaData; int wsaerr; WORD wVersionRequested = MAKEWORD(2, 2); wsaerr = WSAStartup(wVersionRequested, &wsaData); // Check for initialization success if (wsaerr != 0) { std::cout << "The Winsock dll not found!" << std::endl; return 0; } else { std::cout << "The Winsock dll found" << std::endl; std::cout << "The status: " << wsaData.szSystemStatus << std::endl; } return 0; }
Step 2: Create a Socket
Next, we create a socket to handle
communication. The socket()
function is
used for this purpose. It allows us to specify the address family,
socket type, and protocol. In our case, we are creating a TCP socket:
// Create a socket SOCKET serverSocket; serverSocket = INVALID_SOCKET; serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Check for socket creation success if (serverSocket == INVALID_SOCKET) { std::cout << "Error at socket(): " << WSAGetLastError() << std::endl; WSACleanup(); return 0; } else { std::cout << "Socket is OK!" << std::endl; }
Step 3: Bind the Socket
Now, we bind the socket to a specific IP address and port number. This is crucial for the server to listen for incoming connections:
// Bind the socket to an IP address and port number sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr("127.0.0.1"); // Replace with your desired IP address service.sin_port = htons(55555); // Choose a port number // Use the bind function if (bind(serverSocket, reinterpret_cast<SOCKADDR*>(&service), sizeof(service)) == SOCKET_ERROR) { std::cout << "bind() failed: " << WSAGetLastError() << std::endl; closesocket(serverSocket); WSACleanup(); return 0; } else { std::cout << "bind() is OK!" << std::endl; }
Step 4: Listen for Connections
Now, we make the server listen for incoming
connections using the listen()
function:
// Listen for incoming connections if (listen(serverSocket, 1) == SOCKET_ERROR) { std::cout << "listen(): Error listening on socket: " << WSAGetLastError() << std::endl; } else { std::cout << "listen() is OK! I'm waiting for new connections..." << std::endl; }
Step 5: Accept Connections
When a client attempts to connect, the server
uses the accept()
function to accept the
incoming connection:
// Accept incoming connections SOCKET acceptSocket; acceptSocket = accept(serverSocket, nullptr, nullptr); // Check for successful connection if (acceptSocket == INVALID_SOCKET) { std::cout << "accept failed: " << WSAGetLastError() << std::endl; WSACleanup(); return -1; } else { std::cout << "accept() is OK!" << std::endl; }
Step 6: Receive and Send Data
Now that the server is set up and connected to a client, it can send and receive data. The following code demonstrates receiving data and sending a response:
// Receive data from the client char receiveBuffer[200]; int rbyteCount = recv(acceptSocket, receiveBuffer, 200, 0); if (rbyteCount < 0) { std::cout << "Server recv error: " << WSAGetLastError() << std::endl; return 0; } else { std::cout << "Received data: " << receiveBuffer << std::endl; } // Send a response to the client char buffer[200]; std::cout << "Enter the message: "; std::cin.getline(buffer, 200); int sbyteCount = send(acceptSocket, buffer, 200, 0); if (sbyteCount == SOCKET_ERROR) { std::cout << "Server send error: " << WSAGetLastError() << std::endl; return -1; } else { std::cout << "Server: Sent " << sbyteCount << " bytes" << std::endl; }
Creating the Client
Now that we have our server code, let’s set up a simple client to connect to the server and exchange messages.
Step 1: Initialize Winsock and Create a Socket
This step is similar to what we did in the server. Initialize Winsock and create a socket:
#include <iostream> #include <winsock2.h> int main() { // Initialize WSA variables WSADATA wsaData; int wserr; WORD wVersionRequested = MAKEWORD(2, 2); wserr = WSAStartup(wVersionRequested, &wsaData); // Check for initialization success if (wsaerr != 0) { std::cout << "The winsock dll not found" << std::endl; return 0; } else { std::cout << "The Winsock dll found" << std::endl; std::cout << "The status: " << wsaData.szSystemStatus << std::endl; } // Create a socket SOCKET clientSocket; clientSocket = INVALID_SOCKET; clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Check for socket creation success if (clientSocket == INVALID_SOCKET) { std::cout << "Error at socket(): " << WSAGetLastError() << std::endl; WSACleanup(); return 0; } else { std::cout << "Socket is OK!" << std::endl; } // Continue with the client setup... // (See the full code here: https://github.com/Tharun8951/cpp-tcp-server/") return 0; }
Step 2: Connect to the Server
Connect the client to the server using the
connect()
function:
// Connect to the server sockaddr_in clientService; clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr("127.0.0.1"); // Replace with the server's IP address clientService.sin_port = htons(55555); // Use the same port as the server // Use the connect function if (connect(clientSocket, reinterpret_cast<SOCKADDR*>(&clientService), sizeof(clientService)) == SOCKET_ERROR) { std::cout << "Client: connect() - Failed to connect: " << WSAGetLastError() << std::endl; WSACleanup(); return 0; } else { std::cout << "Client: Connect() is OK!" << std::endl; std::cout << "Client: Can start sending and receiving data..." << std::endl; }
Step 3: Send and Receive Data
Similar to the server, the client can now send and receive data:
// Sending data to the server char buffer[200]; std::cout << "Enter the message: "; std::cin.getline(buffer, 200); int sbyteCount = send(clientSocket, buffer, 200, 0); if (sbyteCount == SOCKET_ERROR) { std::cout << "Client send error: " << WSAGetLastError() << std::endl; return -1; } else { std::cout << "Client: Sent " << sbyteCount << " bytes" << std::endl; } // Receiving data from the server char receiveBuffer[200]; int rbyteCount = recv(clientSocket, receiveBuffer, 200, 0); if (rbyteCount < 0) { std::cout << "Client recv error: " << WSAGetLastError() << std::endl; return 0; } else { std::cout << "Client: Received data: " << receiveBuffer << std::endl; } // Continue with the client setup...
Comments
Post a Comment