#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

long _stksize = 20000;

int
main()
{
	struct sockaddr_in sin;
	int fd, r, i;

	sin.sin_family = AF_INET;
/* bind to the local address */	
	sin.sin_addr.s_addr = htonl (INADDR_ANY);
/* bind to an unused port */
	sin.sin_port = htons (0);

	fd = socket (PF_INET, SOCK_DGRAM, 0);
	if (fd < 0) {
		perror ("socket");
		return 0;
	}

	r = bind (fd, (struct sockaddr *)&sin, sizeof (sin));
	if (r < 0) {
		perror ("bind");
		return 0;
	}

	r = sizeof (sin);
	r = getsockname (fd, (struct sockaddr *)&sin, &r);
	if (r < 0) {
		perror ("getsockname");
		return 0;
	}

	printf ("My socket name is: \n\tport = %u \n\taddr = %lx\n",
		sin.sin_port,
		sin.sin_addr.s_addr);

#ifdef DO_CHECKSUM
/* turn on checksum generation */
	r = 1;
	r = setsockopt (fd, SOL_SOCKET, SO_CHKSUM, &r, sizeof (r));
	if (r < 0) {
		perror ("setsockopt");
		return 1;
	}
#endif
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
	sin.sin_port = htons (5555);

	r = connect (fd, (struct sockaddr *)&sin, sizeof (sin));
	if (r < 0) {
		perror ("connect");
		return 0;
	}

#define FACT	400

	for (i = 1; i < 20; ++i) {
		static char buf[8000];

		r = write (fd, buf, i*FACT);
		if (r != i*FACT) {
			perror ("write");
			return 0;
		}
	}
	for (i = 1; i < 20; ++i) {
		static char buf[8000];

		r = read (fd, buf, sizeof (buf));
		if (r != i*FACT) {
			perror ("read");
			return 0;
		}
		printf ("Got Ack %d\n", i);
	}
	return 0;
}
