Connecting to a Socket
This section details how to establish a connection from a client application to a server application using Winsock. Establishing a connection is a fundamental step in many network communication protocols, enabling two endpoints to exchange data reliably.
The connect Function
The primary function used to initiate a connection to a remote socket is connect. This function is used by a client socket to establish a connection to a server socket.
int connect(
SOCKET s,
const struct sockaddr *name,
int namelen
);
Parameters
s: A descriptor identifying a socket.name: A pointer to asockaddrstructure that specifies the address of the remote socket. For TCP/IP, this is typically ansockaddr_instructure.namelen: The length, in bytes, of the structure pointed to by thenameparameter.
Return Value
- If the connection is successful,
connectreturns zero. - If the connection is not successful,
connectreturnsSOCKET_ERROR, and a specific error code can be retrieved by callingWSAGetLastError.
Remarks
When you call connect on a stream socket (like a TCP socket), it attempts to establish a connection to the specified remote address. If the socket is non-blocking, connect will return immediately. If the connection is still in progress, it returns WSAEWOULDBLOCK. You can then use select or WSAEventSelect to determine when the connection has been established or has failed.
For connection-oriented protocols like TCP, connect performs the entire three-way handshake. If the handshake completes successfully, the socket is connected.
Example: Connecting a TCP Client
The following snippet illustrates how a TCP client might attempt to connect to a server listening on a specific IP address and port.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
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
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
std::cerr << "socket failed: " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
//----------------------------------------------------------------------
//----------------------- CLIENT CODE ----------------------------------
//----------------------------------------------------------------------
// The sockaddr_in structure specifies the address family, IP address,
// and port for the server that you want to connect to.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1"); // Server IP address
clientService.sin_port = htons(27015); // Server port
//----------------------------------------------------------------------
//----------------------- CALL connect() -------------------------------
//----------------------------------------------------------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR *) &clientService, sizeof(clientService));
if (iResult == SOCKET_ERROR) {
std::cerr << "connect failed: " << WSAGetLastError() << std::endl;
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
std::cout << "Connected to server!" << std::endl;
// At this point, you can send and receive data.
// ...
// Clean up the socket and Winsock
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Important Considerations
- Ensure that the server application is already running and listening on the specified address and port before attempting to connect.
- Handle
WSAEWOULDBLOCKappropriately if using non-blocking sockets. - Error checking is crucial after every Winsock function call.