Loading...
Select Version
&pagelevel(3)&pagelevel
Das folgende Server-Programm für den verbindungsorientierten Dienst ist in "Verbindungsorientiertes Client/Server-Modell" näher erläutert. Der Server baut eine Transportverbindung mit einem Client auf und übergibt dann eine Protokolldatei an diesen Client. Die Verbindung wird mit dem geordneten Verbindungsabbau der Transportschnittstelle aufgelöst. Der zuvor dargestellte Client im verbindungsorientierten Dienst kann mit dem hier beschriebenen Server kommunizieren.
#include <xti.h> #include <stropts.h> #include <fcntl.h> #include <stdio.h> #include <netinet/in.h> #include <sys/socket.h> #define FILENAME "/etc/services" #define DISCONNECT -1 #define SRV_ADDR 0x7F000001 #define SRV_PORT 8888 int conn_fd; /* Verbindungsaufbau */ main() { int listen_fd; /* Transportendpunkt überwachen */ struct t_bind *bind; struct t_call *call; struct sockaddr_in *sin; if ((listen_fd = t_open("/dev/tcp", O_RDWR, NULL)) < 0) { t_error("t_open() gescheitert für listen_fd"); exit(1); } if ((bind = (struct t_bind *)t_alloc(listen_fd,T_BIND, T_ALL)) == NULL) { t_error("t_alloc() der Struktur t_bind gescheitert"); exit(2); } bind->qlen = 1; 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(listen_fd, bind, bind) < 0) { t_error("t_bind() für listen_fd gescheitert"); exit(3); } if ((call = (struct t_call *)t_alloc(listen_fd,T_CALL, T_ALL)) == NULL) { t_error("t_alloc() von t_call-Struktur gescheitert"); exit(5); } for(;;) { if (t_listen(listen_fd, call) < 0) { t_error("t_listen() für listen_fd gescheitert"); exit(6); } if ((conn_fd = accept_call(listen_fd, call)) != DISCONNECT) run_server(listen_fd); } } accept_call(listen_fd, call) int listen_fd; struct t_call *call; { int resfd; struct t_call *refuse_call; if ((resfd = t_open("/dev/tcp", O_RDWR, NULL)) < 0) { t_error("t_open() für antwortenden fd gescheitert"); exit(7); } while (t_accept(listen_fd, resfd, call) < 0) { if (t_errno == TLOOK) { if (t_look(listen_fd) == T_DISCONNECT) { /* Verbindungsabbruch */ if (t_rcvdis(listen_fd, NULL) < 0) { t_error("t_rcvdis() gescheitert für listen_fd"); exit(9); } if (t_close(resfd) < 0) { t_error("t_close gescheitert für antwortenden fd"); exit(10); } /* Aufruf beenden und auf weiteren Aufruf warten */ return(DISCONNECT); } else { /* neues T_LISTEN; Ereignis löschen */ if ((refuse_call = (struct t_call*)t_alloc(listen_fd,T_CALL,0)) == NULL) { t_error("t_alloc() für refuse_call gescheitert"); exit(11); } if (t_listen(listen_fd, refuse_call) < 0) { t_error("t_listen() für refuse_call gescheitert"); exit(12); } if (t_snddis(listen_fd, refuse_call) < 0) { t_error("t_snddis() für refuse_call gescheitert"); exit(13); } if (t_free((char *)refuse_call, T_CALL) < 0) { t_error("t_free() für refuse_call gescheitert"); exit(14); } } } else { t_error("t_accept() gescheitert"); exit(15); } } return(resfd); } run_server(listen_fd) int listen_fd; { int nbytes; FILE *logfp; /* Dateizeiger auf Log-Datei */ char buf[1024]; switch (fork()) { case -1: perror("fork gescheitert"); exit(20); break; default: /* Elternprozess */ /* conn_fd schließen und wieder als Monitor aktiv sein */ if (t_close(conn_fd) < 0) { t_error("t_close() für conn_fd gescheitert"); exit(21); } return; case 0: /* Kind */ /* listen_fd schließen und Dienst ausführen */ if (t_close(listen_fd) < 0) { t_error("t_close() für listen_fd gescheitert"); exit(22); } if ((logfp = fopen(FILENAME, "r")) == NULL) { perror("Logdatei kann nicht geöffnet werden"); exit(23); } if (t_look(conn_fd) != 0) { /* gab es eine Unterbrechung? */ 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); } }