Loading...
Select Version
&pagelevel(3)&pagelevel
Das folgende Serverprogramm für den verbindungsorientierten Dienst ist im Abschnitt "Weiterführende Konzepte von XTI(POSIX)" näher erläutert. Der Server verwaltet mehrere Verbindungsanforderungen auf ereignisgesteuerte Art. Jeder der zuvor in diesem Kapitel vorgestellten verbindungsorientierten Clients kann mit diesem Server kommunizieren.
#include <xti.h> #include <fcntl.h> #include <stdio.h> #include <poll.h> #include <netinet/in.h> #include <sys/socket.h> #define FILENAME "/etc/services" #define NUM_FDS 1 #define MAX_CONN_IND 4 #define SRV_ADDR 0x7F000001 #define SRV_PORT 8888 int conn_fd; /* Verbindung zum Server */ /* Zum Speichern der Verbindungen */ struct t_call *calls[NUM_FDS][MAX_CONN_IND]; main() { struct pollfd pollfds[NUM_FDS]; struct t_bind *bind; struct sockaddr_in *sin; int i; /* * Nur Öffnen und Binden eines Transportendpunkts, * obwohl das auch für mehr möglich wäre */ if ((pollfds[0].fd = t_open("/dev/tcp", O_RDWR, NULL)) < 0) { t_error("t_open() gescheitert"); exit(1); } if ((bind = (struct t_bind *)t_alloc(pollfds[0].fd, T_BIND, T_ALL)) == NULL) { t_error("t_alloc() der t_bind-Structur gescheitert"); exit(2); } bind->qlen = MAX_CONN_IND; bind->addr.len=sizeof(struct sockaddr_in); sin=(struct sockaddr_in *)bind->addr.buf; sin->sin_family=AF_INET; sin->sin_port=htons(SRV_PORT); sin->sin_addr.s_addr=htonl(SRV_ADDR); if (t_bind(pollfds[0].fd, bind, bind) < 0) { t_error("t_bind() gescheitert"); exit(3); } pollfds[0].events = POLLIN; for(;;) { if (poll(pollfds, NUM_FDS, -1) < 0) { perror("poll() gescheitert"); exit(5); } for (i = 0; i < NUM_FDS; i++) { switch (pollfds[i].revents) { default: perror( "poll gibt Fehlerereignis zurück"); exit(6); break; case 0: continue; case POLLIN: do_event(i, pollfds[i].fd); service_conn_ind(i, pollfds[i].fd); } } } } do_event(slot, fd) { struct t_discon *discon; int i; switch (t_look(fd)) { default: fprintf(stderr,"t_look: unerwartetes Ereignis\n"); exit(7); break; case -1: t_error("t_look() gescheitert"); exit(9); break; case 0: /* Wenn POLLIN zurückgeliefert wird, sollte dies nicht vorkommen */ fprintf(stderr,"Von t_look() kein Ereignis zurückgegeben\n"); exit(10); case T_LISTEN: /* * freies Element im Aufruf-Bereich finden */ for (i = 0; i < MAX_CONN_IND; i++) { if (calls[slot][i] == NULL) break; } if ((calls[slot][i] = (struct t_call *)t_alloc(fd, T_CALL, T_ALL)) == NULL) { t_error("t_alloc() von t_call-Struktur gescheitert"); exit(11); } if (t_listen(fd, calls[slot][i]) < 0) { t_error("t_listen() gescheitert"); exit(12); } break; case T_DISCONNECT: discon = (struct t_discon *)t_alloc(fd, T_DIS, T_ALL); if (t_rcvdis(fd, discon) < 0) { t_error("t_rcvdis() gescheitert"); exit(13); } /* * call ind im Bereich finden und löschen */ for (i = 0; i < MAX_CONN_IND; i++) { if (discon->sequence == calls[slot][i]->sequence) { t_free(calls[slot][i], T_CALL); calls[slot][i] = NULL; } } t_free(discon, T_DIS); break; } } service_conn_ind(slot, fd) { int i; for (i = 0; i < MAX_CONN_IND; i++) { if (calls[slot][i] == NULL) continue; if ((conn_fd = t_open("/dev/tcp", O_RDWR, NULL)) < 0) { t_error("t_open() gescheitert"); exit(14); } if (t_accept(fd, conn_fd, calls[slot][i]) < 0) { if (t_errno == TLOOK) { t_close(conn_fd); return; } t_error("t_accept() gescheitert"); exit(16); } t_free(calls[slot][i], T_CALL); calls[slot][i] = NULL; run_server(fd); } } run_server(listen_fd) int listen_fd; { int nbytes; FILE *logfp; /* Zeiger auf Log-Datei */ char buf[1024]; switch (fork()) { case -1: perror("fork() gescheitert"); exit(20); break; default: /* Vaterprozess */ /* conn_fd schliessen und wieder überwachen */ if (t_close(conn_fd) < 0) { t_error("t_close() gescheitert für conn_fd"); exit(21); } return; case 0: /* Kindprozess */ /* listen_fd schliessen und Dienst ausführen */ if (t_close(listen_fd) < 0) { t_error("t_close() gescheitert für listen_fd"); exit(22); } if ((logfp = fopen(FILENAME, "r")) == NULL) { perror("Logfile kann nicht geöffnet werden"); exit(23); } if (t_look(conn_fd) != 0) { /* gibt es schon disconnect? */ fprintf(stderr, "t_look: unerwartetes Ereignis\n"); exit(25); } while ((nbytes = fread(buf, 1, 1024, logfp)) > 0) if (t_snd(conn_fd, buf, nbytes, 0) < 0) { t_error("t_snd() gescheitert"); exit(26); } if (t_sndrel(conn_fd) < 0) { t_error("t_sndrel() gescheitert"); exit(27); } while(t_look(conn_fd) == 0) { sleep(1); } if(t_look(conn_fd) == T_DISCONNECT) { fprintf(stderr, "Verbindung abgebrochen\n"); exit(12); } exit(0); } }