Einführung in die Netzwerkprogrammierung:tcpclient v6.c

aus PUG, der Penguin User Group
Wechseln zu: Navigation, Suche
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef __hpux
#include <unistd.h>
#endif
#ifdef __sun
#include <unistd.h>
#endif

#define MAX_STRING_SIZE 1024
#define MAX_HOSTNAME_LEN 64
#define MAX_PORT_LEN 6
	
int main (int argc, char ** argv) {
	int fd, ret;
	char server_addr[MAX_HOSTNAME_LEN], server_port[MAX_PORT_LEN];
	int slen;
	char string[MAX_STRING_SIZE], returnstring[MAX_STRING_SIZE];
	char straddr[INET6_ADDRSTRLEN];
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	void *in_addr;

	/* Check for arguments - hostname and portnumber required */
	if (argc<3) {
		printf("Too few arguments\n");
		printf("Usage: %s <hostname> <port>\n\n", argv[0]);
		exit(1);
	}
	strncpy(server_addr, argv[1], MAX_HOSTNAME_LEN-1);
	server_addr[MAX_HOSTNAME_LEN-1] = '\0';
	strncpy(server_port, argv[2], MAX_PORT_LEN-1);
	server_port[MAX_PORT_LEN-1] = '\0';
	
	/* Prepare struct for getaddrinfo */
       memset(&hints, 0, sizeof(struct addrinfo));
       hints.ai_family = AF_UNSPEC;     /* Allow IPv4 or IPv6 */
       hints.ai_socktype = SOCK_STREAM; /* TCP socket */
       hints.ai_flags = 0;
       hints.ai_protocol = 0;           /* Any protocol */

 	/* Determine network addresses of hostname */ 
       ret = getaddrinfo(server_addr, server_port, &hints, &result);
       if (ret != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
        	exit(ret);
       }

	/* Loop through all found addresses and try to connect */
	for (rp = result; rp != NULL; rp = rp->ai_next) {
		fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (fd == -1) 
			continue;
		if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
            break;                  /* Success */
        close(fd);
	}
	if (rp == NULL) {               /* No address succeeded */
		fprintf(stderr, "Could not connect\n");
		exit(-1);
	}
	/* Determine IP family of found address */
	switch (rp->ai_family)
	{
		case AF_INET:
		{
			/* IPv4 found */
			struct sockaddr_in *s4 = (struct sockaddr_in *)rp->ai_addr;
			in_addr = &s4->sin_addr;
			break;
		}
		case AF_INET6:
		{
			/* IPv6 found */
			struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)rp->ai_addr;
			in_addr = &s6->sin6_addr;
			break;
		}
	}
	/* Convert IP address into printable format */
	inet_ntop(rp->ai_family, in_addr, straddr, sizeof(straddr));
	printf("Connection to %s (%s) on port %s established!\n", server_addr, straddr, server_port);
	freeaddrinfo(result);           /* No longer needed */

	/* Read from stdin */
	while((fgets(string, MAX_STRING_SIZE, stdin))>0) {
		slen=strlen(string)+1;
		/* Hang up if only enter was pressed */
		if (slen==2) {
			printf("Closing connection\n");
			close(fd);
			exit(0);
		}
		printf("Sending %d chars\n", slen);
		/* Send chars to server */
		write(fd, string, slen);
		/* Receive answer from server */
		slen=read(fd, returnstring, sizeof(returnstring));
		printf("Server answered: %s\n", returnstring);
	}
}