Commit 24a16790 authored by Sebastian Schinzel's avatar Sebastian Schinzel

Initale Version, noch unformatiert.

parent 9f80770c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 31337
#define BUFFER_SIZE 1024
int sockfd; // Socket-Filedescriptor
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen = sizeof(cli_addr);
fd_set fds; // Filedescriptor-Set
int maxfd;
/**
* Fehlerbehandlung.
*/
void error(char *msg) {
fprintf(stderr, "%s\n", msg);
exit(1);
}
/**
* Erstellt und Konfiguriert den Netzwerk-Socket, ÃŒber den die Verbindungen
* angenommen werden.
*/
void setup_socket() {
int opt = 1;
/*
* Setzt Konfigurationsvariablen fÃŒr den Socket, z.B. die Portnummer.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
/*
* Erstelle den Socket.
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
/*
* Verwende den Socket, selbst wenn er aus einer vorigen AusfÃŒhrung
* im TIME_WAIT Status ist.
*/
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char *)&opt,sizeof(int));
/*
* Melde, dass der Socket eingehende Verbindungen akzeptieren soll.
*/
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
/*
* Horche auf dem Socket nach eingehenden Verbindungen. Es werden maximal
* fÃŒnf gleichzeitige Verbindungen erlaubt.
*/
listen(sockfd, 5);
/*Lege fest in welchem 'Bereich' spÀter select() 'warten' soll. ( hier: 0 - 3)*/
maxfd = 1 + ((sockfd > STDIN_FILENO) ? sockfd : STDIN_FILENO);
}
/**
* Die Hauptschleife, in der eingehende Verbindungen angenommen werden.
*/
void main_loop() {
int length = 0;
char* buffer = malloc(BUFFER_SIZE);
if(buffer == NULL) {
error("ERROR at malloc.");
}
/*
* Die Hauptschleife des Programms.
*/
while (1) {
/* "Datenhygiene" */
bzero(buffer, BUFFER_SIZE);
/*'Zero' das FD-Set (Set besteht aus sockfd und STDIN)*/
FD_ZERO(&fds);
/*Setze Bits(/Flags) der FDs neu*/
FD_SET(sockfd, &fds);
FD_SET(STDIN_FILENO, &fds);
/* select() erlaubt es auf mehrere file descriptors (FD_SETs)
(z.B. socket und stdin) zu warten, bis einer "ready" fÃŒr
jegliche I/O operation (z.B. 'read()' ) ist. */
select(maxfd, &fds, NULL, NULL, NULL);
//Input aus der Konsole:
if (FD_ISSET(STDIN_FILENO, &fds)){
length = read(STDIN_FILENO, buffer, BUFFER_SIZE - 1);
// Testweise Server sauber beenden mit '.' als Input ÃŒber Konsole
if(buffer[0]=='.')
break;
if (length < 0)
error("ERROR reading from stdin");
}
//Input aus Socket
if (FD_ISSET(sockfd, &fds)){
const int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
length = read(newsockfd, buffer, BUFFER_SIZE - 1);
if (length < 0)
error("ERROR reading from socket");
/*
* Schreibe die ausgehenden Daten auf den Socket zurÃŒck.
*/
length = write(newsockfd, buffer, length);
if (length < 0)
error("ERROR writing to socket");
/*
* Schließe die Verbindung.
*/
close(newsockfd);
}
/*
* Gib die eingegangenen Daten (zusÀtzlich) auf der Kommandozeile aus.
*/
length = write(STDIN_FILENO, buffer, length);
if (length < 0)
error("ERROR writing to stdin");
}
/*
* Lösche den Buffer und schließe den Socket. Dieser Aufruf sollte wegen der
* Endlosschleife niemals ausgefÃŒhrt werden.
*/
free(buffer);
close(sockfd);
}
int main(int argc, char *argv[]) {
setup_socket();
main_loop();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment