home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / cellsim / v2_5 / socket / datagrph.c next >
Encoding:
C/C++ Source or Header  |  1990-02-26  |  6.0 KB  |  247 lines

  1. /****************************************\
  2. *                                        *
  3. *           datagraph.c               *
  4. *                         *
  5. *    read & graph data from a socket     *
  6. *                                        *
  7. *      for use with CA simulator        *
  8. *                                        *
  9. *                                        *
  10. \****************************************/
  11.  
  12. /* Aug 30 1988 */
  13.  
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/time.h>
  17. #include <netinet/in.h>
  18. #include <netdb.h>
  19. #include <stdio.h>
  20. #define TRUE 1
  21. #define FALSE 0
  22. #define MAXLEN 32
  23. #define set_bit(b, ptr) ((*(ptr)) |= (1 << (b)))
  24. #define test_bit(b, ptr) ((*(ptr)) & (1 << (b)))
  25. #define clear_all_bits(ptr)  (*(ptr) = 0)
  26.  
  27. #include <pixrect/pixrect_hs.h>
  28. #include <suntool/sunview.h>
  29. #include <suntool/canvas.h>
  30.  
  31. /*
  32.  * Format of socket messages from CA simulator is as follows:  The first message
  33.  * is a single integer, giving the number of states per cell currently in use.
  34.  * Subsequent messages are sent once every CA time step; each message is a list
  35.  * of integers, one per state, giving a count of the number of cells in the current
  36.  * array with that state.
  37.  */
  38.  
  39. /*
  40.  * This program creates a socket and then begins an infinite loop.  Each time
  41.  * through the loop it accepts a connection and reads messages from it.  The
  42.  * first message is assumed to be a single integer, giving the length (in
  43.  * integers) of all subsequent messages.  The subsequent messages are then
  44.  * read, and the first two numbers are graphed against each other as fractions
  45.  * of the total of all numbers.  (When the numbers are from the CA simulator,
  46.  * this gives a graph of percentage of state 0 vs. percentage of state 1.)
  47.  *
  48.  * When the connection breaks, or a termination message comes through, the
  49.  * program accepts a new connection.
  50.  *
  51.  * Note that this program is more complicated than dataread, since it must
  52.  * process SunView notifier events while waiting for messages.
  53.  *
  54.  * Compile line:  cc -o datagraph datagraph.c -lsuntool -lsunwindow -lpixrect
  55.  */
  56.  
  57. int     sock, msgsock;
  58. int     ready;
  59. struct timeval to;
  60.  
  61. /* graphics vars */
  62. Frame   frame;
  63. Canvas  canvas;
  64. Pixwin *pw;
  65.  
  66. #define MAXSIZE 512
  67. #define MM1 511                /* MAXSIZE - 1 */
  68.  
  69.  
  70.  
  71. main()
  72. {
  73.     int     buf[MAXLEN], rval, msglen;
  74.     int     i;
  75.     int     total, x, y, xprev, yprev;
  76.     extern Notify_error notify_dispatch();
  77.  
  78.     setup_receiver();
  79.     init_graph();
  80.  
  81.     do {
  82.     if (check_receiver()) {
  83.         connect_receiver();
  84.         clear_graph();
  85.         rval = get_message(&msglen, 1);
  86.         if (rval != 0) {
  87.         rval = get_message(buf, msglen);    /* get first message */
  88.         total = 0;
  89.         for (i = 0; i < msglen; i++)    /* calculate totals */
  90.             total += buf[i];
  91.         xprev = (float) buf[0] / total * MAXSIZE;
  92.         yprev = (float) buf[1] / total * MAXSIZE;
  93.         plot_point(xprev, yprev);
  94.         while (rval != 0) {
  95.             bzero(buf, sizeof(buf));
  96.             rval = get_message(buf, msglen);    /* get further messages */
  97.             if (rval == 0)
  98.             break;
  99.             x = (float) buf[0] / total * MAXSIZE;
  100.             y = (float) buf[1] / total * MAXSIZE;
  101.             plot_line(xprev, yprev, x, y);
  102.             xprev = x;
  103.             yprev = y;
  104.         }
  105.         }
  106.         disconnect_receiver();
  107.     } else
  108.         notify_dispatch();        /* handle Sunwindow events */
  109.     } while (TRUE);
  110.  
  111.     /*
  112.      * Since this program has an infinite loop, the socket "sock" is never
  113.      * explicitly closed.  However, all sockets will be closed automatically
  114.      * when a process is killed or terminates normally.
  115.      */
  116.  
  117.     close_receiver();
  118. }
  119.  
  120.  
  121. /***** SOCKET ROUTINES *****/
  122.  
  123. setup_receiver()
  124. {
  125.     struct sockaddr_in server;
  126.     int     length;
  127.  
  128.     /* Create socket */
  129.     sock = socket(AF_INET, SOCK_STREAM, 0);
  130.     if (sock < 0) {
  131.     perror("opening stream socket");
  132.     exit(1);
  133.     }
  134.     /* Name socket using wildcards */
  135.     server.sin_family = AF_INET;
  136.     server.sin_addr.s_addr = INADDR_ANY;
  137.     server.sin_port = 0;
  138.     if (bind(sock, &server, sizeof(server))) {
  139.     perror("binding stream socket");
  140.     exit(1);
  141.     }
  142.     /* Find out assigned port number and print it out */
  143.     length = sizeof(server);
  144.     if (getsockname(sock, &server, &length)) {
  145.     perror("getting socket name");
  146.     exit(1);
  147.     }
  148.     fprintf(stderr, "Socket has port #%d\n", ntohs(server.sin_port));
  149.  
  150.     /* Start accepting connections */
  151.     listen(sock, 5);
  152. }
  153.  
  154. check_receiver()
  155. {
  156.     clear_all_bits(&ready);
  157.     set_bit(sock, &ready);
  158.     to.tv_sec = 0;
  159.     to.tv_usec = 100000;        /* 0.1 sec. */
  160.     if (select(sock + 1, &ready, 0, 0, &to) < 0) {
  161.     perror("select");
  162.     return (FALSE);
  163.     } else
  164.     return (test_bit(sock, &ready));
  165. }
  166.  
  167. connect_receiver()
  168. {
  169.     msgsock = accept(sock, 0, 0);
  170.     if (msgsock == -1) {
  171.     perror("accept");
  172.     exit(1);
  173.     }
  174. }
  175.  
  176. disconnect_receiver()
  177. {
  178.     close(msgsock);
  179. }
  180.  
  181. get_message(data, len)            /* Receives len integers into array data.
  182.                      * Returns 0 if connection closed. */
  183.     int    *data, len;
  184. {
  185.     int     r, go = FALSE;
  186.     while (!go) {            /* wait until there is an incoming
  187.                      * message */
  188.     notify_dispatch();
  189.     /* update screen while waiting */
  190.     clear_all_bits(&ready);
  191.     set_bit(msgsock, &ready);
  192.     to.tv_sec = 0;
  193.     to.tv_usec = 100000;        /* 0.1 sec. */
  194.     if (select(msgsock + 1, &ready, 0, 0, &to) < 0) {
  195.         perror("select");
  196.         go = FALSE;
  197.     } else
  198.         go = test_bit(msgsock, &ready);
  199.     }
  200.  
  201.     if ((r = read(msgsock, (char *) data, len * sizeof(int))) < 0)
  202.     perror("reading stream message");
  203.     if (r == 0)
  204.     fprintf(stderr, "Ending connection\n");
  205.     return (r);
  206. }
  207.  
  208. close_receiver()
  209. {
  210.     close(sock);
  211. }
  212.  
  213.  
  214. /***** GRAPHING ROUTINES *****/
  215.  
  216. init_graph()
  217. {
  218.     frame = window_create(NULL, FRAME, FRAME_LABEL, "CA graph",
  219.               WIN_SHOW, TRUE, 0);
  220.     canvas = window_create(frame, CANVAS,
  221.                CANVAS_WIDTH, MAXSIZE, CANVAS_HEIGHT, MAXSIZE,
  222.                WIN_HEIGHT, MAXSIZE, WIN_WIDTH, MAXSIZE, 0);
  223.     window_fit(frame);
  224.     pw = canvas_pixwin(canvas);
  225.  
  226. } /* init_graph */
  227.  
  228. clear_graph()
  229. {
  230.     pw_writebackground(pw, 0, 0, MAXSIZE, MAXSIZE, PIX_SRC);
  231. }
  232.  
  233. plot_point(x, y)
  234.     int     x, y;
  235. {
  236.     pw_put(pw, x, MM1 - y, 1);
  237. }
  238.  
  239. plot_line(x0, y0, x1, y1)
  240.     int     x0, y0, x1, y1;
  241. {
  242.     pw_vector(pw, x0, MM1 - y0, x1, MM1 - y1, PIX_SRC, 1);
  243. }
  244.  
  245.  
  246. /***** END OF FILE *****/
  247.