TCP Client Example

The following example code demonstrates the implementation of a TCP client. The client connects to a specified host, with an optional port/service name, and resource string. The client then sends an HTTP/1.1 GET request to the server, and outputs the response.

 1#include <err.h>
 2#include <netdb.h>
 3#include <stdint.h>
 4#include <stdio.h>
 5#include <stdlib.h>
 6#include <string.h>
 7#include <sys/socket.h>
 8#include <sys/types.h>
 9#include <unistd.h>
10
11#define BUF_SIZE 500
12
13int
14main(int argc, char *argv[])
15{
16  char const *host;
17  char const *service = "http";
18  char const *resource = "/";
19  switch (argc) {
20    case 4:
21      resource = argv[3];
22    case 3:
23      service = argv[2];
24    case 2:
25      host = argv[1];
26      break;
27    default:
28      err(1, "Usage: %s host [port] [resource]\n", argv[0]);
29  }
30
31  struct addrinfo hints = {
32      .ai_family = AF_UNSPEC,     /* IPv4 or IPv6 */
33      .ai_socktype = SOCK_STREAM, /* Stream Socket */
34  };
35
36  struct addrinfo *result, *rp;
37  int s;
38  s = getaddrinfo(host, service, &hints, &result);
39  if (s != 0) errx(1, "getaddrinfo: %s\n", gai_strerror(s));
40
41  /* getaddrinfo() returns a list of address structures.
42     Try each address until we successfully bind(2).
43     If socket(2) (or bind(2)) fails, we (close the socket
44     and) try the next address. */
45  int sock_fd;
46  for (rp = result; rp != NULL; rp = rp->ai_next) {
47    sock_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
48    if (sock_fd == -1) continue;
49    if (connect(sock_fd, rp->ai_addr, rp->ai_addrlen) == 0) break; /* Success */
50    close(sock_fd);
51  }
52  freeaddrinfo(result); /* No longer needed */
53  if (rp == NULL) err(1, "could not connect to %s:%s", host, service);
54
55  /* Send request */
56  dprintf(sock_fd, "GET %s HTTP/1.1\r\n"
57                   "Host: %s\r\n\r\n", resource, host);
58  shutdown(sock_fd, SHUT_WR);
59
60  for (;;) {
61    char buf[BUFSIZ];
62    size_t n = read(sock_fd, buf, sizeof buf);
63    if (n < 0) err(1, "read");
64    if (n == 0) break;
65    fwrite(buf, 1, n, stdout);
66  }
67  close(sock_fd);
68}