static char rcsid[] = "$Id: tcpserv.c,v 1.1 2001/12/02 12:13:52 as Exp as $"; /************************************************************************ * * Example of server using TCP protocol. * ***********************************************************************/ #include #include // open() #include "inet.h" #include "error.cpp" #include "util.cpp" #include #include #include using namespace std; // Constant definitions // // maximum line length const int MAXLINE=255; // structure for phone book records struct telEintrag { // Einzelne Einträge im Telefonbuch char name[50]; char tel[50]; }; // max. 50 records in a phone book // global variables // // TODO: change to file or shared memory // global variables are not good with fork() // telEintrag telBuch[50]; // 50 Einträge möglich int telCount = 0; // Position des nächsten freien Platzes // write a line to socket sockfd void myWrite(int sockfd, char *line) { int n; // send reply n = strlen(line); if (writen(sockfd, line, n) != n) { err_dump("str_echo: writen error"); } } // read line from socket sockfd void myRead(int sockfd, char *line) { int n; // receive data into line n = readline(sockfd, line, MAXLINE); // error handling if (n == 0) { return; /* connection terminated */ } else if (n < 0) { err_dump("str_echo: readline error"); } // console logging // time_t structure variable myTime time_t myTime; // read time into myTime time(&myTime); // char array for time conversion char tmpTime[25]; // copy converted time into char array strcpy(tmpTime, ctime(&myTime)); // append string terminating binary 0 tmpTime[strlen(tmpTime)-1] = '\0'; // print time and received line to stdout printf("[%s] Nachricht: %s",tmpTime,line); } void str_echo(int sockfd) { int n; char line[MAXLINE]; for ( ; ; ) { // read line from socket myRead(sockfd, line); // if "addEntry"-command was sent if (strcmp(line, "addEntry\n") == 0) { // send back "OK", we understood the command myWrite(sockfd, "OK\n"); // now we receive the name myRead(sockfd, line); // name received myWrite(sockfd, "OK\n"); // save it in local memory strcpy(telBuch[telCount].name, line); // now we receive the phone number myRead(sockfd, line); // number received myWrite(sockfd, "OK\n"); // save the number in local memory strcpy(telBuch[telCount].tel, line); // next time we fill the next array element telCount++; // we did it printf("Neuer Eintrag im Telefonbuch.\n"); } else // the "searchEntry"-command was sent if (strcmp(line, "searchEntry\n") == 0) { // send back "OK", we understood the command myWrite(sockfd, "OK\n"); // receive the search string myRead(sockfd, line); // search the entry int i=0; bool found = false; for (i; i < telCount; i++) { if (strcmp(telBuch[i].name, line) == 0) { found = true; // we found an entry // send back the phone number myWrite(sockfd, telBuch[i].tel); } } // we did not find anything if (found == false) myWrite(sockfd, "Nicht gefunden.\n"); } else if (strcmp(line,"end\n")==0) { // client sent end command // exiting... myWrite(sockfd,"Server exiting... \n"); exit(0); } else { // an undefined command was sent from client myWrite(sockfd, "Command not found.\n"); } } } /***********************************************************************/ /************************************************************************ * main function, server for the TCP/IP echo server */ int main(int argc, char **argv) { int sockfd, newsockfd, clilen, childpid; // structures of socket addresses struct sockaddr_in cli_addr, serv_addr; pname = argv[0]; // Open a TCP socket (an Internet stream socket). if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_dump("server: can't open stream socket"); // Bind our local address so that the client can send to us. // make sure zeros are in serv_addr bzero((char *) &serv_addr, sizeof(serv_addr)); // now fill in information, which we need serv_addr.sin_family = AF_INET; // INADDR_ANY: System definiton -> accept connections on every interface // htonl: convert byte order (host to network long) serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // SERV_TCP_PORT defined in inet.h // htons: convert byte order (host to network short) serv_addr.sin_port = htons(SERV_TCP_PORT); // bind sockfd to socket address serv_addr (Server) if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) err_dump("server: can't bind local address"); // mark socket to accept connections // limit 5 connections backlog in queue listen(sockfd, 5); for ( ; ; ) { // Wait for a connection from a client process. // This is an example of a concurrent server. clilen = sizeof(cli_addr); // make new socket for client connection and return // the file descriptor of this socket newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *) &clilen); if (newsockfd < 0) err_dump("server: accept error"); if ( (childpid = fork()) < 0) err_dump("server: fork error"); else if (childpid == 0) { // child process printf("Verbinung aufgebaut.\n"); close(sockfd); // close original socket str_echo(newsockfd); // process the request exit(0); } close(newsockfd); // parent process } } /***********************************************************************/