Loading...
Select Version
&pagelevel(3)&pagelevel
The following server program for the connection-oriented service is described in detail in section "Advanced XTI(POSIX) concepts". The server manages several connection requests in an event-controlled manner. All of the connection-oriented clients described earlier in this chapter can communicate with this server.
#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; /* Connection to server */ /* For storing the connections */ 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; /* * Only open and bind one transport endpoint, * although it would also be possible for more */ if ((pollfds[0].fd = t_open("/dev/tcp", O_RDWR, NULL)) < 0) { t_error("t_open() failed"); exit(1); } if ((bind = (struct t_bind *)t_alloc(pollfds[0].fd, T_BIND, T_ALL)) == NULL) { t_error("t_alloc() of the t_bind structure failed"); 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() failed"); exit(3); } pollfds[0].events = POLLIN; for(;;) { if (poll(pollfds, NUM_FDS, -1) < 0) { perror("poll() failed"); exit(5); } for (i = 0; i < NUM_FDS; i++) { switch (pollfds[i].revents) { default: perror( "Poll returns error event"); 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: unexpected event\n"); exit(7); break; case -1: t_error("t_look() failed"); exit(9); break; case 0: /* If POLLIN is returned, this should not happen */ fprintf(stderr,"No event returned from t_look()\n"); exit(10); case T_LISTEN: /* * Find free member in call area */ 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() of t_call structure failed"); exit(11); } if (t_listen(fd, calls[slot][i]) < 0) { t_error("t_listen() failed"); 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() failed"); exit(13); } /* * Find and delete ind call in area */ 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() failed"); 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() failed"); 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; /* Pointer to log file */ char buf[1024]; switch (fork()) { case -1: perror("fork() failed"); exit(20); break; default: /* Parent process */ /* Close conn_fd and monitor again */ if (t_close(conn_fd) < 0) { t_error("t_close() failed for conn_fd"); exit(21); } return; case 0: /* Child process */ /* Close listen_fd and execute service */ if (t_close(listen_fd) < 0) { t_error("t_close() failed for listen_fd"); exit(22); } if ((logfp = fopen(FILENAME, "r")) == NULL) { perror("Log file cannot be opened"); exit(23); } if (t_look(conn_fd) != 0) { /* Is there already a disconnect? */ fprintf(stderr, "t_look: unexpected event\n"); exit(25); } while ((nbytes = fread(buf, 1, 1024, logfp)) > 0) if (t_snd(conn_fd, buf, nbytes, 0) < 0) { t_error("t_snd() failed"); exit(26); } if (t_sndrel(conn_fd) < 0) { t_error("t_sndrel() failed"); exit(27); } while(t_look(conn_fd) == 0) { sleep(1); } if(t_look(conn_fd) == T_DISCONNECT) { fprintf(stderr, "Connection aborted\n"); exit(12); } exit(0); } }