/* * * Tue Sep 23 19:34:20 DST 2003 * Sample tcp client * * :set tabstop=4 * */ static char __ident[] = "@(#)SPDsoft, Fri Nov 18 11:30:18 CET 2005"; #include #include /* va_ */ #include /* atoi */ #if defined(__MACH__) && defined(__APPLE__) #include #endif #include /* getpid */ #include /* getpid */ #include #include #include #include #include #include #include #include #include #include #include #ifndef INADDR_NONE # define INADDR_NONE (in_addr_t)-1 #endif struct prefs { char *hostname; unsigned int port; unsigned int bs; int answers; int read_stdin; int debug; unsigned int timeout; }; int debug=0; int open_tcp_server( char *host, struct sockaddr_in *server_addr, unsigned int port, unsigned timeout ); int close_tcp_server(int fd); void g_init(int argc,char **argv,struct prefs*); int recv_bcast(int s, struct sockaddr_in server_addr, int answers, unsigned timeout); void debug_msg(const char *fmt, ...); #define perror(e) debug_msg("%s (%s)\n", e, strerror(errno)) void debug_msg(const char *fmt, ...) { va_list vl; if (debug) { va_start(vl,fmt); vfprintf(stderr,fmt,vl); va_end(vl); fflush(stderr); } } #ifndef BS #define BS 8192 #endif int main(int argc, char *argv[]) { struct prefs pref; int server; struct sockaddr_in server_addr; int l; unsigned char buffer[BS+2]; size_t n,ns; long long count=0; int answers=0; unsigned char parity=0; g_init(argc,argv,&pref); debug_msg("Trying: %s:%d...\n",pref.hostname, pref.port); if (-1 == (server=open_tcp_server( pref.hostname, &server_addr, pref.port, pref.timeout))) { fprintf(stderr, "Conection can't be established\n"); } else { fprintf(stderr, "#### Starting broadcast\n"); while ( 0 < ( n = read( 0, buffer+2, pref.bs ))) { answers=pref.answers; parity++; *buffer=parity; if ( 0 >= ( ns=sendto( server, buffer, n+2, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)))) { perror("client: sendto failed"); } count ++; debug_msg("%d %d bytes packets sent %d %d\n", count, ns, parity, *buffer); l=recv_bcast(server, server_addr, answers, pref.timeout); while ( l != answers ) { fprintf(stderr, "#### Missing packet %d != %d!\n",l,answers); if ( 0 >= ( ns=sendto( server, buffer, n+2, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)))) { perror("client: sendto failed"); } debug_msg("%d %d bytes packets sent - retry %d\n", count, ns, parity); l=recv_bcast(server, server_addr, answers, pref.timeout); } } close_tcp_server(server); } } void g_init(int argc,char **argv,struct prefs *pref) { extern char *optarg; extern int optind,opterr,optopt; int option; unsigned char err=0; pref->hostname="localhost"; pref->port=80; pref->timeout=5; pref->bs=512; pref->answers=1; pref->debug=0; pref->read_stdin=0; while((option=getopt(argc,argv,"dcH:p:s:B:ct:a:")) != EOF ) { switch(option) { case 'd': pref->debug=1; debug=1; break; case 'c': pref->read_stdin=1; break; case 'B': pref->bs=(unsigned short) atoi(optarg); if ( pref->bs > BS) err++; break; case 'H': pref->hostname=optarg; break; case 'p': pref->port =(unsigned short) atoi(optarg); break; case 't': pref->timeout =(unsigned short) atoi(optarg); break; case 'a': pref->answers =(unsigned short) atoi(optarg); break; default: err++; break; } } if ( err != 0 ) { fprintf( stderr, "Use: %s -H host -p port -B buffsize -a answers -t timeout -cd\n", argv[0]); exit(-1); } } /*****************************************************************************/ int open_tcp_server( char *host, struct sockaddr_in *server_addr, unsigned int port, unsigned timeout ) { int sockfd; int i=1, n; unsigned long addr; struct hostent *he; struct sockaddr_in peer; struct sockaddr_in local; alarm(timeout); /* * Broadcast: we need a datagram UDP socket */ if ( 0 > (sockfd = socket(AF_INET,SOCK_DGRAM,0))) { perror("client: can't open stream socket"); alarm(0); return(-1); } addr = inet_addr(host); if (addr == INADDR_NONE) { he = gethostbyname(host); if (he == NULL) { perror("gethostbyname: no IP address found"); alarm(0); return(-1); } addr = ((struct in_addr *)(he->h_addr))->s_addr; } memset(&peer,0,sizeof(peer)); peer.sin_family = AF_INET; peer.sin_addr.s_addr = addr; peer.sin_port = htons(port); memset(&local,0,sizeof(local)); local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; local.sin_port = 0; if (bind(sockfd, (struct sockaddr *) &local, sizeof(local))) { perror("client: can't bind socket"); alarm(0); close(sockfd); return(-1); } if ( 0 > ( setsockopt( sockfd, SOL_SOCKET,SO_BROADCAST, (void *)&i,sizeof(i)))) { perror("client: failure to set SO_BROADCAST"); close(sockfd); alarm(0); return(-1); } memcpy(server_addr,&peer,sizeof(peer)); alarm(0); return sockfd; } /*****************************************************************************/ int close_tcp_server(int fd) { return(close(fd)); } /*****************************************************************************/ int recv_bcast(int s, struct sockaddr_in server_addr, int answers, unsigned timeout) { double n=0; unsigned long n_p=0; long nbytes; struct sockaddr_in server, client; int clientlen=sizeof(client); int fd; unsigned char buf[BS]; int done; int end=0; uint32_t sum; unsigned char *req; int err; struct timeval tv; fd_set mask, rmask; int nfound; int maxfd; int reuse=1; tv.tv_sec = timeout; tv.tv_usec = 0; done=0; FD_ZERO(&mask); FD_SET(s, &mask); maxfd=s; for(;!end && (done