DS UNIX TCP/IP-Server in C
(Adapted) Winsock-Codes von Daniel Schwamm (31.03.1998)
UNIX-TCP/IP-Server in C
/*****************************************************************************
UNIX-TCP/IP-Server:
Hauptprozess richtet sockfd ein, der auf bestimmten Socket
lauscht. Wenn Client-Anfrage kommt, dann wird fork() aufgerufen.
Child arbeitet Client ab, während Parent wieder in Lauschzustand
geht (==> paralleler Server).
Zugehöriger Client: DS_WinClient.txt
Von: Daniel Schwamm (www.daniel-schwamm.de)
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stropts.h>
#define SERV_HOST_ADDR "194.1.1.1"
#define MAXCMD 3000
char RESULTTEXT[MAXCMD];
int SERV_TCP_PORT,sockfd,newsockfd;
DoLoginJob(char *RESULTTEXT){...};
DoHurz(char *RESULTTEXT){...};
/*****************************************************************************
Hole eine Kommandozeile vom Client
*****************************************************************************/
int GetCMD(int sockfd,char *cmd){
int n;
if((n=recv(sockfd,cmd,MAXCMD,0))<0){
sprintf(RESULTTXT,"%s#Konnte Kommando nicht empfangen#",CNSERR);
return 0;
}
cmd[n]=0;
return 1;
}
/*****************************************************************************
Sende eine Kommandozeile an den Client
*****************************************************************************/
int SendCMD(int sockfd,char *cmd){
int n,l;
l=strlen(cmd);
if((n=send(sockfd,cmd,l,0))<0){
sprintf(RESULTTXT,"%s#Konnte Kommando <%s> nicht senden#",CNSERR,cmd);
return 0;
}
return 1;
}
/*****************************************************************************
diverse aufräumarbeiten
*****************************************************************************/
void hndlsigurgs(){
shutdown(sockfd,2);
exit(-1);
}
/*****************************************************************************
diverse aufräumarbeiten
*****************************************************************************/
void hndlsigurgc(){
shutdown(newsockfd,2);
exit(-1);
}
/*****************************************************************************
Abarbeiten der Kinder-Prozesse. Hierzu werden zuerst die Client-Kommandos
empfangen und dann entspr. Unterprogramme aufgerufen.
*****************************************************************************/
void ChildProc(int sockfd){
signal(SIGURG,hndlsigurgc);
GetCMD(sockfd,CMD);
if(strlcmp(CMD,"LOGIN",5)==0){
DoLoginJob(RESULTTEXT);
SendCMD(sockfd,RESULTTXT);
}
else if(strcmp(WRD,"HURZ")==0){
DoHurzJob(RESULTTEXT);
SendCMD(sockfd,RESULTTXT);
}
else{
sprintf(RESULTTXT,"%s#Unbekanntes Kommando <%s>#",CNSERR,CMD);
SendCMD(sockfd,RESULTTXT);
}
}
/*****************************************************************************
Hauptprogramm: Einrichten des CNS-Servers. Der Server lauscht auf seinem
Socket, bis ein Client sich meldet. Mit fork() wird der Prozess kopiert.
Der Server geht wieder in den Lauschzustand ueber, waehrend der Child-Prozess
die Client-Anfrage abarbeitet.
*****************************************************************************/
void main(int argc,char *argv[]){
int clilen,childpid;
struct sockaddr_in cli_addr,serv_addr;
char fname[200];
int n,i,dum,optlen;
FILE *logout;
char ch;
SERV_TCP_PORT=4500;
/* Verhindere dreckige Zombis, indem Child-Results ignoriert werden */
signal(SIGCLD,SIG_IGN);
signal(SIGURG,hndlsigurgs);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
printf("CNS-ERROR: Kann Streamsocket nicht oeffnen");
exit(-1);
}
optlen=sizeof(dum);
if(
setsockopt(
sockfd,
SOL_SOCKET,
SO_REUSEADDR,
(char*)&dum,
optlen
)<0
){
printf("CNS-ERROR: Kann Optionen nicht oeffnen");
exit(-1);
}
memset((char*)&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(SERV_TCP_PORT);
if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0){
MsgLast("CNS-ERROR: Kann lokale Adresse nicht binden");
exit(-1);
}
printf("OK: CarNet-Server erfolgreich gestartet. Warte auf Clients ...");
clientc=0;
listen(sockfd,5);
for(;;){
clilen=sizeof(cli_addr);
newsockfd=accept(sockfd,(struct sockaddr*)&cli_addr,&clilen);
clientc++;
if(newsockfd<0){
MsgLast("CNS-ERROR: ACCEPT-Fehler");
exit(-1);
}
if((childpid=fork())<0){
MsgLast("CNS-ERROR: FORK-Fehler");
exit(-1);
}
else if(childpid==0){
close(sockfd);
ChildProc(newsockfd);
shutdown(newsockfd,2);
exit(0);
}
close(newsockfd);
}
}