1. The Core Logic: connect()

The connect function initiates the TCP “three-way handshake.” When a client calls this function, the kernel sends a SYN (synchronize) segment to the server and waits for a response.

Function Prototype:

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

Returns:

  • Success: 0 (The connection is established).
  • Error: -1 (and errno is set).

2. Breakdown of Arguments

  1. sockfd: The socket descriptor returned by the socket function (from Section 4.2).
  2. servaddr: A pointer to a socket address structure (like struct sockaddr_in) containing the IP address and port number of the server you want to reach.
  3. addrlen: The size of the socket address structure (typically sizeof(servaddr)).

3. Common Errors

This is a critical part of debugging network clients. The text details what happens when connect fails:

  • ETIMEDOUT: The client sent a SYN but received no response.
    • Scenario: The server machine might be turned off, or a firewall is dropping the packets.
    • Behavior: TCP will retry sending the SYN a few times (e.g., at 6s, 24s, 75s) before giving up (often takes about 75 seconds total).
  • ECONNREFUSED: The server machine responded with a RST (Reset) packet.
    • Scenario: The packet reached the server machine, but no process is listening on the specified port. (You dialed the wrong extension).
    • Definition: This is a “hard error.”
  • EHOSTUNREACH or ENETUNREACH: The client received an ICMP “destination unreachable” error from a router.
    • Scenario: The network path to the server is broken, or the host is unreachable.
    • Definition: This is often treated as a “soft error”—the kernel may retry sending the SYN for a while before finally returning this error.

4. Code Example

Here is how you typically set up the address and call connect:

struct sockaddr_in servaddr;
 
// 1. Clear the structure
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
 
// 2. Set the Port (htons converts host-byte-order to network-byte-order)
servaddr.sin_port = htons(13); // Example: Connecting to Daytime server port 13
 
// 3. Set the IP Address (inet_pton converts string to binary IP)
if (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0) {
    err_quit("inet_pton error");
}
 
// 4. Connect
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
    // Check errno here for ETIMEDOUT, ECONNREFUSED, etc.
    err_sys("connect error"); 
}