Changeset 4764


Ignore:
Timestamp:
11/07/08 03:37:29 (8 years ago)
Author:
werner
Message:
  • added README with a list of known issues
  • receiver prints ping-like latency statistics at the end
  • sender supports -c count option, like ping
  • sender properly shuts down the receiver if failing or stopped with SIGINT
Location:
developers/werner/owping
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • developers/werner/owping/Makefile

    r4763 r4764  
    22 
    33CFLAGS=-Wall -Wshadow -g -O 
     4LDFLAGS=-lm 
    45 
    56PREFIX=/usr 
  • developers/werner/owping/owping.c

    r4763 r4764  
    1515#include <stdlib.h> 
    1616#include <stdio.h> 
     17#include <unistd.h> 
    1718#include <arpa/inet.h> 
    1819 
     
    2526static void usage(const char *name) 
    2627{ 
    27     fprintf(stderr, "usage: %s [ip_address]\n", name); 
     28    fprintf(stderr, "usage: %s [[-c count] ip_address]\n", name); 
    2829    exit(1); 
    2930} 
     
    3334{ 
    3435    struct sockaddr_in addr; 
     36    int count = -1; 
     37    int c; 
     38    char *end; 
    3539 
    36     switch (argc) { 
    37     case 1: 
     40    while ((c = getopt(argc, argv, "c:")) != EOF) 
     41        switch (c) { 
     42        case 'c': 
     43            count = strtoul(optarg, &end, 10); 
     44            if (*end) 
     45                usage(*argv); 
     46            break; 
     47        default: 
     48            usage(*argv); 
     49        } 
     50 
     51    switch (argc-optind) { 
     52    case 0: 
    3853        rx(PORT); 
    3954        break; 
    40     case 2: 
     55    case 1: 
    4156        addr.sin_family = AF_INET; 
    42         addr.sin_addr.s_addr = inet_addr(argv[1]); 
     57        addr.sin_addr.s_addr = inet_addr(argv[optind]); 
    4358        addr.sin_port = htons(PORT); 
    4459        if (addr.sin_addr.s_addr == (in_addr_t) -1) 
    4560            usage(*argv); 
    46         tx(addr, 100); 
     61        tx(addr, count); 
    4762        break; 
    4863    default: 
  • developers/werner/owping/rx.c

    r4763 r4764  
    1515#include <stdlib.h> 
    1616#include <stdio.h> 
     17#include <string.h> 
     18#include <math.h> 
    1719#include <sys/time.h> 
    1820#include <sys/socket.h> 
     
    2325 
    2426 
    25 static void delta(struct timeval t0, struct timeval t1) 
     27struct stats { 
     28    long min, max; 
     29    double sum, sq; 
     30    int n; 
     31}; 
     32 
     33 
     34static void stats_init(struct stats *stats) 
    2635{ 
     36    memset(stats, 0, sizeof(*stats)); 
     37} 
     38 
     39 
     40static void stats_print(const char *label, const struct stats *stats) 
     41{ 
     42    double avg = stats->sum/stats->n; 
     43 
     44    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms (%d packets)\n", 
     45      label, 
     46      stats->min/1000.0, avg/1000.0, stats->max/1000.0, 
     47      sqrt(stats->sq/stats->n-avg*avg)/1000.0, 
     48      stats->n); 
     49} 
     50 
     51 
     52static void delta(struct timeval t0, struct timeval t1, struct stats *stats) 
     53{ 
     54    char sign = ' '; 
    2755    long us; 
    2856 
    2957    us = t1.tv_usec-t0.tv_usec; 
    3058    us += (t1.tv_sec-t0.tv_sec)*1000000; 
    31     printf(" %ld.%03ldms", us/1000, us % 1000); 
     59 
     60    if (!stats->n) { 
     61        stats->min = stats->max = us; 
     62    } else { 
     63        if (stats->min > us) 
     64            stats->min = us; 
     65        if (stats->max < us) 
     66            stats->max = us; 
     67    } 
     68    stats->n++; 
     69    stats->sum += us; 
     70    stats->sq += (double) us*us; 
     71 
     72    if (us < 0) { 
     73        us = -us; 
     74        sign = '-'; 
     75    } 
     76    printf(" %c%ld.%03ldms", sign, us/1000, us % 1000); 
    3277} 
    3378 
     
    3580void rx(int port) 
    3681{ 
     82    struct stats stats_itf, stats_user; 
    3783    struct sockaddr_in addr; 
    3884    int s; 
     
    5298    } 
    5399     
    54     // setsockopt timestamp 
     100    stats_init(&stats_itf); 
     101    stats_init(&stats_user); 
    55102 
    56103    while (1) { 
     
    68115        } 
    69116        if (got == 1) 
    70             return; 
     117            break; 
    71118        if (got != sizeof(buf)) { 
    72119            fprintf(stderr, "bad read: expected %u, got %u\n", 
     
    86133        t_src.tv_sec = ntohl(buf.tv_sec); 
    87134        t_src.tv_usec = ntohl(buf.tv_usec); 
    88         delta(t_src, t_itf); 
    89         delta(t_src, t_user); 
     135        delta(t_src, t_itf, &stats_itf); 
     136        delta(t_src, t_user, &stats_user); 
    90137        putchar('\n'); 
    91138    } 
     139    stats_print("itf:", &stats_itf); 
     140    stats_print("app:", &stats_user); 
     141 
    92142} 
  • developers/werner/owping/tx.c

    r4763 r4764  
    1616#include <stdio.h> 
    1717#include <unistd.h> 
     18#include <signal.h> 
    1819#include <sys/time.h> 
    1920#include <sys/socket.h> 
     
    2324 
    2425 
     26static int s; 
     27 
     28 
     29static void cleanup(void) 
     30{ 
     31    write(s, "", 1); 
     32} 
     33 
     34 
     35static void handler(int sig) 
     36{ 
     37    cleanup(); 
     38    _exit(0); 
     39} 
     40 
     41 
    2542void tx(struct sockaddr_in addr, int num) 
    2643{ 
    2744    ssize_t sent; 
    28     int s, seq; 
     45    int seq; 
    2946 
    3047    s = socket(PF_INET, SOCK_DGRAM, 0); 
     
    3956    } 
    4057 
    41     for (seq = 0; seq != num; seq++) { 
     58    if (atexit(cleanup)) { 
     59        perror("atexit"); 
     60        exit(1); 
     61    } 
     62    if (signal(SIGINT, handler) == SIG_ERR) { 
     63        perror("signal(SIGINT)"); 
     64        exit(1); 
     65    } 
     66 
     67    for (seq = 0; num < 0 || seq != num; seq++) { 
    4268        struct owping buf; 
    4369        struct timeval now; 
     
    6490        } 
    6591    } 
    66  
    67     sent = write(s, "", 1); 
    68     if (sent < 0) { 
    69         perror("write"); 
    70         exit(1); 
    71     } 
    72     if (sent != 1) { 
    73         fprintf(stderr, "bad write: %u < 1\n", (unsigned) sent); 
    74         exit(1); 
    75     } 
    7692} 
Note: See TracChangeset for help on using the changeset viewer.