Loading...
Select Version
&pagelevel(3)&pagelevel
The following server program for the connection-oriented service is described in detail in section "Connection-oriented client/server model". The server sets up a transport connection to a client and then passes a protocol file to this client. The connection is shut down using the orderly connection shutdown of the transport interface. The client in the connection-oriented service described in the previous section can communicate with the server described here.
#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; /* Connection setup */ main() { int listen_fd; /* Monitor transport endpoint */ 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() failed for listen_fd"); exit(1); } if ((bind = (struct t_bind *)t_alloc(listen_fd,T_BIND, T_ALL)) == NULL) { t_error("t_alloc() of the t_bind structure failed"); 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() for listen_fd failed"); exit(3); } if ((call = (struct t_call *)t_alloc(listen_fd,T_CALL, T_ALL)) == NULL) { t_error("t_alloc() of t_call structure failed"); exit(5); } for(;;) { if (t_listen(listen_fd, call) < 0) { t_error("t_listen() for listen_fd failed"); 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() for responding fd failed"); exit(7); } while (t_accept(listen_fd, resfd, call) < 0) { if (t_errno == TLOOK) { if (t_look(listen_fd) == T_DISCONNECT) { /* Connection abort */ if (t_rcvdis(listen_fd, NULL) < 0) { t_error("t_rcvdis() failed for listen_fd"); exit(9); } if (t_close(resfd) < 0) { t_error("t_close failed for responding fd"); exit(10); } /* Terminate call and wait for further call */ return(DISCONNECT); } else { /* New T_LISTEN; delete event */ if ((refuse_call = (struct t_call*)t_alloc(listen_fd,T_CALL,0)) == NULL) { t_error("t_alloc() for refuse_call failed"); exit(11); } if (t_listen(listen_fd, refuse_call) < 0) { t_error("t_listen() for refuse_call failed"); exit(12); } if (t_snddis(listen_fd, refuse_call) < 0) { t_error("t_snddis() for refuse_call failed"); exit(13); } if (t_free((char *)refuse_call, T_CALL) < 0) { t_error("t_free() for refuse_call failed"); exit(14); } } } else { t_error("t_accept() failed"); exit(15); } } return(resfd); } run_server(listen_fd) int listen_fd; { int nbytes; FILE *logfp; /* File pointer to log file */ char buf[1024]; switch (fork()) { case -1: perror("fork failed"); exit(20); break; default: /* Parent process */ /* Close conn_fd and remain active as monitor again */ if (t_close(conn_fd) < 0) { t_error("t_close() for conn_fd failed"); exit(21); } return; case 0: /* Child */ /* Close listen_fd and execute service */ if (t_close(listen_fd) < 0) { t_error("t_close() for listen_fd failed"); exit(22); } if ((logfp = fopen(FILENAME, "r")) == NULL) { perror("Log file cannot be opened"); exit(23); } if (t_look(conn_fd) != 0) { /* Was there an interruption? */ 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); } }