Ignore:
Timestamp:
11/09/08 20:39:20 (5 years ago)
Author:
werner
Message:

Make it a bit more convenient to use.

  • the host can now be by specified by name
  • new option -p port to set the port number by name or number
  • receiver prints statistics if interrupted by SIGINT
File:
1 edited

Legend:

Unmodified
Added
Removed
  • developers/werner/owping/rx.c

    r4764 r4775  
    1515#include <stdlib.h> 
    1616#include <stdio.h> 
     17#include <unistd.h> 
    1718#include <string.h> 
    1819#include <math.h> 
     20#include <signal.h> 
    1921#include <sys/time.h> 
    2022#include <sys/socket.h> 
     
    2931    double sum, sq; 
    3032    int n; 
    31 }; 
     33} stats_itf, stats_user; 
    3234 
    3335 
     
    4244    double avg = stats->sum/stats->n; 
    4345 
    44     printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms (%d packets)\n", 
     46    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms\n", 
    4547      label, 
    4648      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      sqrt(stats->sq/stats->n-avg*avg)/1000.0); 
    4950} 
    5051 
     
    7879 
    7980 
    80 void rx(int port) 
     81static void finish(void) 
    8182{ 
    82     struct stats stats_itf, stats_user; 
    83     struct sockaddr_in addr; 
     83    printf("received %d packets\n", stats_itf.n); 
     84    stats_print("itf:", &stats_itf); 
     85    stats_print("app:", &stats_user); 
     86} 
     87 
     88 
     89static void handler(int sig) 
     90{ 
     91    finish(); 
     92    _exit(0); 
     93} 
     94 
     95 
     96static void block(int how) 
     97{ 
     98    sigset_t set; 
     99 
     100    if (sigemptyset(&set) < 0) { 
     101        perror("sigemptyset"); 
     102        exit(1); 
     103    } 
     104    if (sigaddset(&set, SIGINT) < 0) { 
     105        perror("sigaddset"); 
     106        exit(1); 
     107    } 
     108    if (sigprocmask(how, &set, NULL) < 0) { 
     109        perror("sigprocmask"); 
     110        exit(1); 
     111    } 
     112} 
     113 
     114 
     115void rx(const struct sockaddr_in *addr) 
     116{ 
     117    struct sockaddr_in src; 
    84118    int s; 
    85119 
     
    90124    } 
    91125 
    92     addr.sin_family = AF_INET; 
    93     addr.sin_addr.s_addr = INADDR_ANY; 
    94     addr.sin_port = htons(port); 
    95     if (bind(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) { 
     126    if (bind(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) { 
    96127        perror("bind"); 
    97128        exit(1); 
     
    101132    stats_init(&stats_user); 
    102133 
     134    if (atexit(finish)) { 
     135        perror("atexit"); 
     136        exit(1); 
     137    } 
     138    if (signal(SIGINT, handler) == SIG_ERR) { 
     139        perror("signal(SIGINT)"); 
     140        exit(1); 
     141    } 
     142 
    103143    while (1) { 
    104144        struct owping buf; 
     
    107147        struct timeval t_src, t_itf, t_user; 
    108148 
    109         addr_len = sizeof(addr); 
     149        addr_len = sizeof(src); 
    110150        got = recvfrom(s, &buf, sizeof(buf), 0, 
    111           (struct sockaddr *) &addr, &addr_len); 
     151          (struct sockaddr *) &src, &addr_len); 
    112152        if (got < 0) { 
    113153            perror("recvmsg"); 
     
    129169            exit(1); 
    130170        } 
     171        block(SIG_BLOCK); 
    131172        printf("seq=%u from %s:", (unsigned) ntohl(buf.seq), 
    132           inet_ntoa(addr.sin_addr)); 
     173          inet_ntoa(src.sin_addr)); 
    133174        t_src.tv_sec = ntohl(buf.tv_sec); 
    134175        t_src.tv_usec = ntohl(buf.tv_usec); 
     
    136177        delta(t_src, t_user, &stats_user); 
    137178        putchar('\n'); 
     179        block(SIG_UNBLOCK); 
    138180    } 
    139     stats_print("itf:", &stats_itf); 
    140     stats_print("app:", &stats_user); 
    141  
    142181} 
Note: See TracChangeset for help on using the changeset viewer.