home *** CD-ROM | disk | FTP | other *** search
- /****************************************\
- * *
- * datagraph.c *
- * *
- * read & graph data from a socket *
- * *
- * for use with CA simulator *
- * *
- * *
- \****************************************/
-
- /* Aug 30 1988 */
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <stdio.h>
- #define TRUE 1
- #define FALSE 0
- #define MAXLEN 32
- #define set_bit(b, ptr) ((*(ptr)) |= (1 << (b)))
- #define test_bit(b, ptr) ((*(ptr)) & (1 << (b)))
- #define clear_all_bits(ptr) (*(ptr) = 0)
-
- #include <pixrect/pixrect_hs.h>
- #include <suntool/sunview.h>
- #include <suntool/canvas.h>
-
- /*
- * Format of socket messages from CA simulator is as follows: The first message
- * is a single integer, giving the number of states per cell currently in use.
- * Subsequent messages are sent once every CA time step; each message is a list
- * of integers, one per state, giving a count of the number of cells in the current
- * array with that state.
- */
-
- /*
- * This program creates a socket and then begins an infinite loop. Each time
- * through the loop it accepts a connection and reads messages from it. The
- * first message is assumed to be a single integer, giving the length (in
- * integers) of all subsequent messages. The subsequent messages are then
- * read, and the first two numbers are graphed against each other as fractions
- * of the total of all numbers. (When the numbers are from the CA simulator,
- * this gives a graph of percentage of state 0 vs. percentage of state 1.)
- *
- * When the connection breaks, or a termination message comes through, the
- * program accepts a new connection.
- *
- * Note that this program is more complicated than dataread, since it must
- * process SunView notifier events while waiting for messages.
- *
- * Compile line: cc -o datagraph datagraph.c -lsuntool -lsunwindow -lpixrect
- */
-
- int sock, msgsock;
- int ready;
- struct timeval to;
-
- /* graphics vars */
- Frame frame;
- Canvas canvas;
- Pixwin *pw;
-
- #define MAXSIZE 512
- #define MM1 511 /* MAXSIZE - 1 */
-
-
-
- main()
- {
- int buf[MAXLEN], rval, msglen;
- int i;
- int total, x, y, xprev, yprev;
- extern Notify_error notify_dispatch();
-
- setup_receiver();
- init_graph();
-
- do {
- if (check_receiver()) {
- connect_receiver();
- clear_graph();
- rval = get_message(&msglen, 1);
- if (rval != 0) {
- rval = get_message(buf, msglen); /* get first message */
- total = 0;
- for (i = 0; i < msglen; i++) /* calculate totals */
- total += buf[i];
- xprev = (float) buf[0] / total * MAXSIZE;
- yprev = (float) buf[1] / total * MAXSIZE;
- plot_point(xprev, yprev);
- while (rval != 0) {
- bzero(buf, sizeof(buf));
- rval = get_message(buf, msglen); /* get further messages */
- if (rval == 0)
- break;
- x = (float) buf[0] / total * MAXSIZE;
- y = (float) buf[1] / total * MAXSIZE;
- plot_line(xprev, yprev, x, y);
- xprev = x;
- yprev = y;
- }
- }
- disconnect_receiver();
- } else
- notify_dispatch(); /* handle Sunwindow events */
- } while (TRUE);
-
- /*
- * Since this program has an infinite loop, the socket "sock" is never
- * explicitly closed. However, all sockets will be closed automatically
- * when a process is killed or terminates normally.
- */
-
- close_receiver();
- }
-
-
- /***** SOCKET ROUTINES *****/
-
- setup_receiver()
- {
- struct sockaddr_in server;
- int length;
-
- /* Create socket */
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("opening stream socket");
- exit(1);
- }
- /* Name socket using wildcards */
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- server.sin_port = 0;
- if (bind(sock, &server, sizeof(server))) {
- perror("binding stream socket");
- exit(1);
- }
- /* Find out assigned port number and print it out */
- length = sizeof(server);
- if (getsockname(sock, &server, &length)) {
- perror("getting socket name");
- exit(1);
- }
- fprintf(stderr, "Socket has port #%d\n", ntohs(server.sin_port));
-
- /* Start accepting connections */
- listen(sock, 5);
- }
-
- check_receiver()
- {
- clear_all_bits(&ready);
- set_bit(sock, &ready);
- to.tv_sec = 0;
- to.tv_usec = 100000; /* 0.1 sec. */
- if (select(sock + 1, &ready, 0, 0, &to) < 0) {
- perror("select");
- return (FALSE);
- } else
- return (test_bit(sock, &ready));
- }
-
- connect_receiver()
- {
- msgsock = accept(sock, 0, 0);
- if (msgsock == -1) {
- perror("accept");
- exit(1);
- }
- }
-
- disconnect_receiver()
- {
- close(msgsock);
- }
-
- get_message(data, len) /* Receives len integers into array data.
- * Returns 0 if connection closed. */
- int *data, len;
- {
- int r, go = FALSE;
- while (!go) { /* wait until there is an incoming
- * message */
- notify_dispatch();
- /* update screen while waiting */
- clear_all_bits(&ready);
- set_bit(msgsock, &ready);
- to.tv_sec = 0;
- to.tv_usec = 100000; /* 0.1 sec. */
- if (select(msgsock + 1, &ready, 0, 0, &to) < 0) {
- perror("select");
- go = FALSE;
- } else
- go = test_bit(msgsock, &ready);
- }
-
- if ((r = read(msgsock, (char *) data, len * sizeof(int))) < 0)
- perror("reading stream message");
- if (r == 0)
- fprintf(stderr, "Ending connection\n");
- return (r);
- }
-
- close_receiver()
- {
- close(sock);
- }
-
-
- /***** GRAPHING ROUTINES *****/
-
- init_graph()
- {
- frame = window_create(NULL, FRAME, FRAME_LABEL, "CA graph",
- WIN_SHOW, TRUE, 0);
- canvas = window_create(frame, CANVAS,
- CANVAS_WIDTH, MAXSIZE, CANVAS_HEIGHT, MAXSIZE,
- WIN_HEIGHT, MAXSIZE, WIN_WIDTH, MAXSIZE, 0);
- window_fit(frame);
- pw = canvas_pixwin(canvas);
-
- } /* init_graph */
-
- clear_graph()
- {
- pw_writebackground(pw, 0, 0, MAXSIZE, MAXSIZE, PIX_SRC);
- }
-
- plot_point(x, y)
- int x, y;
- {
- pw_put(pw, x, MM1 - y, 1);
- }
-
- plot_line(x0, y0, x1, y1)
- int x0, y0, x1, y1;
- {
- pw_vector(pw, x0, MM1 - y0, x1, MM1 - y1, PIX_SRC, 1);
- }
-
-
- /***** END OF FILE *****/
-