Zdrojový text bez poznámek je zde: client.c.
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv)
{
	int ret = 0;

	argc--, argv++;

	if (!argc) {
		puts("Number of args is wrong. At least one is needed (network "
			"name or address)");
		ret = 1;
		goto out;
Někde někdo napsal/řekl, že používání goto kód znepřehledňuje a způsobuje jeho obtížné čtení. Neměl pravdu. Je jedna výjimka, kde goto dělá přesný opak – toto je ten případ. Potřebuje-li programátor ošetřit několik věcí, jako je uvolnění paměti, zavolání funkcí, které zavírají deskriptory apod., použije goto takovým způsobem, jaký je možné vidět zde.
	}

	struct protoent *pe = getprotobyname("tcp");
Tady se ve struktuře, na kterou odkazuje pe, objeví číslo protokolu, jež odpovídá záznamu v /etc/protocols. Toto číslo použijeme při vytváření struktury ai.
	struct addrinfo *out, ai = {0, PF_UNSPEC, SOCK_STREAM, pe->p_proto, };
Zde není možné nepřehlédnout tu čárku před }. Ano, i toto gcc přeloží. Hlavní ale je, že elementy, které explicintě nenapíšeme do {…} se nastaví na 0.
Stejně tak bych mohl explicitně uvést, které elementy inicializuji: { .ai_family = PF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = pe->p_proto }
Tak a nyní nastal čas zavolat IPv6-ready funkci, která vrátí ukazatel na strukturu držící informace o adrese, na kterou se připojit:
	if (getaddrinfo(argv[0], argv[1] ? : "10001", &ai, &out)) {
A vy se zeptáte: „Co že jsem to tam napsal, ? :?” A já odpovím: „No jasně, tohle gcc přeloží a pokud uživatel zadal 2. parametr, použije se.” V opačném případě se použije impicitní 10001.
		perror("getaddrinfo error");
getaddrinfo, stejně jako bazilion dalších funkcí ukládá svoji chybu do errno, můžeme volat perror, jež za řetězec v parametru vloží ›: ‹ a řetězec popisující chybu uloženou v errno.
		ret = 100;
		goto out;
	}

	switch (out->ai_addr->sa_family) {
Celá tady ta šaškárna je jen kvůli uživatelům – vypíše to protokol, ip a port, na kterou se bude klient připojovat.
	case AF_INET: {
Hack, který donutí gcc4 přeložit deklaraci za case.
		struct sockaddr_in *in =
			(struct sockaddr_in*)out->ai_addr;
		printf("ipv4: %s, %d\n", inet_ntoa(in->sin_addr),
			ntohs(in->sin_port));
		break;
	} case AF_INET6: {
		struct sockaddr_in6 *in6 =
			(struct sockaddr_in6*)out->ai_addr;
		char buf[INET6_ADDRSTRLEN];
		inet_ntop(AF_INET6, (void*)&in6->sin6_addr, buf,
			sizeof(buf));
		printf("ipv6: %s, %d\n", buf, ntohs(in6->sin6_port));
		break;
	} default:
		puts("unknown address class");
		ret = 2;
		goto frout;
	}

	int fd = socket(out->ai_addr->sa_family, SOCK_STREAM, pe->p_proto);
	if (fd < 0) {
		perror("socket error");
		    ret = 3;
		goto frout;
	}

	if (connect(fd, out->ai_addr, out->ai_addrlen)) {
		perror("connect error");
		goto clout;
	}


	int len;
	char buf[128];
	struct timeval tv = {5, 0};
	fd_set fs;

	FD_ZERO(&fs);
	FD_SET(0, &fs);
	FD_SET(fd, &fs);
Bude třeba obsluhovat 2 deskriptory zároveň (standardní vstup a spojení), proto musíme použít nějaký mechanizmus, který ohlídá, zda na některém z nich není připraveno něco ke čtení. Zde zvítězil select.

	while (select(fd + 1, &fs, NULL, NULL, &tv) >= 0) {
		if (FD_ISSET(0, &fs)) {
			if ((len = read(0, buf, sizeof(buf))))
( a ) se píše, protože gcc kontroluje = a ==, pokud napíšete 1, myslí si, že je to překlep a vypíše varování.
				send(fd, buf, len, 0);
			else
				goto clout;
Uživatel stiskl EOF.
		}

		if (FD_ISSET(fd, &fs)) {
			if ((len = recv(fd, buf, sizeof(buf), 0)))
				write(0, buf, len);
			else {
				puts("Server ends the relation");
				goto clout;
			}
		}

		FD_ZERO(&fs);
		FD_SET(0, &fs);
		FD_SET(fd, &fs);
		tv.tv_sec = 5;
		tv.tv_usec = 0;
	}

	perror("select error");

clout:
	close(fd);

frout:	
	freeaddrinfo(out);

out:
	return ret;
}