/* * Simple Jitter program (client side) * Alcatel Alenia Space - 2006 * GPL Licence * Author: Nicolas Hennion */ #include "jitter.h" /* Global variables */ int socketfd; struct sockaddr_in serveraddr; int main(int argc, char **argv) { socklen_t slen=sizeof(serveraddr); struct hostent *hptr; char *buf, server_ip[BUFFER_INET4_ADDR], server_name[BUFFER_CHAR]; extern char *optarg; int i, errflag=1, n_flag=0, t_flag=0; int packet_number=DEFAULT_PACKET_NUMBER, time_number=DEFAULT_TIME_NUMBER; int port_number=DEFAULT_PORT_NUMBER, buffer_size=DEFAULT_BUFFER_SIZE, bitrate=DEFAULT_BITRATE; double begin=0, end=0, sendbegin=0, sendend=0, lastprogressbar=0; unsigned long packet_delay, packet_size; /* Manage arguments */ while ((i = getopt(argc, argv, "c:n:t:p:w:b:v")) != EOF) { switch (i) { case 'c': strncpy(server_name, optarg, BUFFER_CHAR); if ((hptr = gethostbyname(server_name)) == NULL) { fprintf(stderr, "Invalid server IP address or name...\n"); errflag = 1; } else { inet_ntop(hptr->h_addrtype, *(hptr->h_addr_list), server_ip, sizeof(server_ip)); errflag = 0; } break; case 'n': sscanf(optarg, "%d", &packet_number); n_flag = 1; if ((packet_number < 2) || (packet_number > MAX_PACKET_NUMBER) || t_flag) errflag = 1; break; case 't': sscanf(optarg, "%d", &time_number); t_flag = 1; if ((time_number < 2) || n_flag) errflag = 1; break; case 'p': sscanf(optarg, "%d", &port_number); if ((port_number < 1024) || (port_number > MAX_PORT_NUMBER)) errflag = 1; break; case 'w': sscanf(optarg, "%d", &buffer_size); if ((buffer_size < MIN_BUFFER_SIZE) || (buffer_size > MAX_BUFFER_SIZE)) errflag = 1; break; case 'b': sscanf(optarg, "%d", &bitrate); if (bitrate < 11 ) errflag = 1; break; case 'v': fprintf(stderr, "version: sjitter client version %s\n", SJITTERC_VERSION); errflag = 1; break; } } if (errflag) { fprintf(stderr, "usage: sjitterc -c SERVER [[-n NBPCKT] | [-t SECOND]] [-p PORTNB] [-w SIZE] [-b BITRAT]\n"); fprintf(stderr, "\t-c SERVER: where SERVER is the server IP address or name\n"); fprintf(stderr, "\t-n NBPCKT: where NCPCKT is the number of datagram (>1 , <%d) [default:%d]\n", MAX_PACKET_NUMBER, DEFAULT_PACKET_NUMBER); fprintf(stderr, "\t-t SECOND: where SECOND is the number of second (>1) [default:%d]\n", DEFAULT_PACKET_NUMBER); fprintf(stderr, "\t-p PORTNB: where PORTNB is the port number (>1024, <%d) [default:%d]\n", MAX_PORT_NUMBER, DEFAULT_PORT_NUMBER); fprintf(stderr, "\t-w SIZE: where SIZE is the application buffer size (bytes) (>%d, <%d) [default:%d]\n", MIN_BUFFER_SIZE, MAX_BUFFER_SIZE, DEFAULT_BUFFER_SIZE); fprintf(stderr, "\t-b BITRATE: where BITRATE is the bitrate (IP level) in Kbps (>10) [default:%d]\n", DEFAULT_BITRATE); if (n_flag && t_flag) { fprintf(stderr, "It is not possible to use -n and -t in the same command line\n"); } exit(2); } /* Buffer allocation */ buf = (char *) malloc(buffer_size); /* Signals management */ signal(SIGINT, onsignal); signal(SIGTERM, onsignal); signal(SIGQUIT, onsignal); /* Build the socket */ if ((socketfd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) errorexit("socket"); memset((char *) &serveraddr, sizeof(serveraddr), 0); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(port_number); if (inet_aton(server_ip, &serveraddr.sin_addr)==0) perror("inet_aton"); if (t_flag) { /* -t option set, compute the packet number */ packet_number = (time_number*(bitrate*1000.0))/((buffer_size+28)*8); } else { /* Compute the estimate time */ time_number = (packet_number*((buffer_size+28)*8))/(bitrate*1000.0); } printf("Send data (%d datagrams of %d bytes / %d Kbps) to the server:port %s:%d\n", packet_number, buffer_size, bitrate, inet_ntoa(serveraddr.sin_addr), port_number); /* Send configuration datagram to the server */ snprintf(buf, buffer_size, "SJITTER-START %d %d ", packet_number, buffer_size); if (sendto(socketfd, buf, buffer_size, 0, (const struct sockaddr *) &serveraddr, slen)==-1) errorexit("sendto"); /* Compute delay for bitrate (goal on the IP level) */ packet_size = (unsigned long) ((buffer_size+28)*8); packet_delay = (unsigned long) ((packet_size/(bitrate*1000.0))*1000000); /* Send data to the server */ /* Init the packet number tag */ i=0; /* Star the main loop */ printf("Sending data (estimate time: %d seconds)...\n", time_number); begin = lastprogressbar = getcurrenttimems(); while (i 1) { progressbar(i, packet_number); lastprogressbar = sendend; } /* Next packet */ i++; } end = getcurrenttimems(); /* Send "SJITTER-END" datagram to the server */ snprintf(buf, buffer_size, "SJITTER-END "); if (sendto(socketfd, buf, buffer_size, 0, (const struct sockaddr *) &serveraddr, slen)==-1) errorexit("sendto"); /* Summary */ printf("\r \r"); printf("Summary: %d datagrams sent in %.2lf seconds (%.0lf Kbps)\n", packet_number, end-begin, (packet_number*buffer_size*8)/(end-begin)/1000); close(socketfd); free(buf); return 0; }