Kategorie: C

Design Pattern by Gamma und Co.

18 Jan

Jeder gute Programmierer sollte die grundlegenen Design Pattern von Gamma und Co. kennen. Für eine kleine 2-seitige Übersicht ist jetzt mit den Design Pattern Cards gesorgt.

Solche Pattern (Muster) helfen Probleme schnell und sauber zu lösen. Man kann sich damit sicher sein, eine gute Lösung zu nutzen und greift auf die langjährige Erfahrung einer ganzen Community zurück. Also, jeder sollte 5-10 Pattern kennen und auch anwenden können, ihr haltet damit euren Code wesentlich sauberer und besser wartbar!

 

Minimaler TCP Server & TCP Client in C

29 Jun

Ich habe mal einen minimalen Server in C geschrieben, mit dem passenden Client dazu. Es gibt wirklich nur die grundlegende ASCII Kommunikation, kein Protokoll oder ähnliches. Natürlich läuft die Verbindung intern über TCP/IP etc. Es gibt jedoch kein Protokoll auf Netzwerk-Ebene 5.

Der Server:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <string.h>
#include <arpa/inet.h>
 
int main(void) {
	/* Socket erstellen - TCP, IPv4, keine Optionen */
	int lsd = socket(AF_INET, SOCK_STREAM, 0);
 
	/* IPv4, Port: 1111, jede IP-Adresse akzeptieren */
	struct sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(1111);
	saddr.sin_addr.s_addr = htons(INADDR_ANY);
 
	/* Socket an Port binden */
	bind(lsd, (struct sockaddr*) &saddr, sizeof(saddr));
 
	/* Auf Socket horchen (Listen) */
	listen(lsd, 10);
 
	while(1) {
		/* Puffer und Strukturen anlegen */
		struct sockaddr_in clientaddr;
		char buffer[10];
		bzero(buffer, sizeof(buffer));
 
		/* Auf Verbindung warten, bei Verbindung Connected-Socket erstellen */
		socklen_t clen = sizeof(clientaddr);
		int csd = accept(lsd, (struct sockaddr*) &clientaddr, &clen);
 
		/* Vom Client lesen und ausgeben */
		int bytes = recv(csd, buffer, sizeof(buffer), 0);
		printf("Der Client hat folgenden String gesendet: %s\n", buffer);
		printf("Es wurden %d Bytes empfangen\n", bytes);
 
		/* Verbindung schließen */
		close(csd);
	}
 
	return EXIT_SUCCESS;
 
}

Der Client:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
 
int main(void) {
	/* Socket erstellen */
	int socks = socket(AF_INET, SOCK_STREAM, 0);
 
	/* Verbindungsziel festlegen, Port und IP-Adresse des Servers angeben */
	struct sockaddr_in serveraddr;
	bzero(&serveraddr, sizeof(serveraddr));
	inet_pton(AF_INET, "127.0.0.1", &serveraddr);
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(1111);
 
	/* Verbindung aufbauen */
	connect(socks, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
 
	/* Puffer mit Text füllen */
	char buffer[5];
	strcpy(buffer, "test");
 
	/* "test" String an Server senden */
	int bytes = send(socks , buffer, sizeof(buffer), 0);
 
	/* Ausgabe was gesendet wurde */
	printf("Sende String: %s\n", buffer);
	printf("Es wurden %d Bytes gesendet\n", bytes);
 
	/* Verbindung beenden */
	close(socks);
 
	return EXIT_SUCCESS;
}

Die Ausgabe der beiden C Programmie sieht so aus:

VM-Ubuntu:~/Desktop$ gcc -Wall -o server TCPServer.c
VM-Ubuntu:~/Desktop$ gcc -Wall -o client TCPClient.c
VM-Ubuntu:~/Desktop$ ./server
Der Client hat folgenden String gesendet: test
Es wurden 5 Bytes empfangen

VM-Ubuntu:~/Desktop$ ./client
Sende String: test
Es wurden 5 Bytes gesendet

Das Ganze ist, wie man sieht, sehr minimalistisch gehalten, aber so kann man denke ich am besten verstehen was passiert und wie die Netzwerkprogrammierung in C funktioniert. Falls ihr die Programme selber kompilieren wollt, benötigt ihr den aktuellen gcc (oder ähnlichen C Compiler) und die passenden Bibliotheken (unter Ubuntu build-essentials installieren)!