Einführung in die Netzwerkprogrammierung:tcpserver.c

aus PUG, der Penguin User Group
Wechseln zu: Navigation, Suche
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>

#define MAX_STRING_SIZE 1024

int main (int argc, char ** argv) {
	int fdc, fdd;
	char string[MAX_STRING_SIZE], *p;
	struct sockaddr_in local, remote;
	int server_port, rlen, slen;

	if (argc<2) {
		printf("too few arguments\n");
		printf("Usage: %s <port>\n\n", argv[0]);
		exit(1);
	}
	server_port=atoi(argv[1]);
	if (server_port==0) {
		printf("invalid port number\n");
		exit(1);
	}

	// open TCP socket
	printf("Starting TCP server on port %d - ", server_port);
	if ((fdc=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("tcp socket error");
		exit(errno);
	}

	local.sin_family=AF_INET;
	// listen on port <server_port>
	local.sin_port=htons(server_port);
	// listen on any ip interface
	local.sin_addr.s_addr=htonl(INADDR_ANY);
	memset(&local.sin_zero, 0, sizeof(local.sin_zero));

	// bind and listen on port and ip interface
	if (bind(fdc, (struct sockaddr*)&local, sizeof(local)) < 0) {
		perror("tcp bind error");
		exit(errno);
	}
	if (listen(fdc, 15) < 0) {
		perror("tcp listen error");
		exit(errno);
	}
	printf("success\n");

	while(1) {
  	rlen=sizeof(remote);
	// accept connection
	if ((fdd=accept(fdc, (struct sockaddr*)&remote, &rlen)) < 0) {
		perror("accept error");
		exit(errno);
	}
	// create child to be able to get multiple connections
	switch(fork()) {
		case -1: 
			perror("fork error");
			exit(errno);
		case 0:
			// child process: read tcp data
			close(fdc);
			printf("Got TCP-Connection from %s\n", inet_ntoa(remote.sin_addr));
			while ((slen=read(fdd, string, sizeof(string)))>0) {
				// whatever you want to do with the data...
				// in this case we just convert it and send it back
				for (p=string; p<string+slen; p++) {
					if (isalpha(*p)) *p=(islower(*p) ? toupper(*p) : tolower(*p));
				}
				write(fdd, string, slen);
			}
			printf("TCP-Connection closed\n");
			exit(0);
		default:
			// parent process: prepare for new connections
			close(fdd);
			break;
		}
	}
}