11 #include <netinet/in.h>
12 #include <arpa/inet.h>
20 static struct timeval start_time;
21 static unsigned long long kb_sent;
23 static unsigned long mtime_since(struct timeval *s, struct timeval *e)
27 sec = e->tv_sec - s->tv_sec;
28 usec = e->tv_usec - s->tv_usec;
29 if (sec > 0 && usec < 0) {
35 usec /= (double) 1000;
40 static unsigned long mtime_since_now(struct timeval *s)
44 gettimeofday(&t, NULL);
45 return mtime_since(s, &t);
48 void show_rate(int sig)
50 unsigned long msecs = mtime_since_now(&start_time);
55 printf("Throughput: %LuMiB/sec (%Lu MiB in %lu msecs)\n", kb_sent / msecs, kb_sent, msecs);
58 int main(int argc, char *argv[])
60 struct sockaddr_in addr;
66 printf("%s: target port\n", argv[0]);
70 if (fstat(STDIN_FILENO, &sb) < 0)
72 if (!S_ISFIFO(sb.st_mode)) {
73 fprintf(stderr, "stdin must be a pipe\n");
79 memset(&addr, 0, sizeof(addr));
80 addr.sin_family = AF_INET;
81 addr.sin_port = htons(port);
83 if (inet_aton(argv[1], &addr.sin_addr) != 1) {
84 struct hostent *hent = gethostbyname(argv[1]);
87 return error("gethostbyname");
89 memcpy(&addr.sin_addr, hent->h_addr, 4);
92 printf("Connecting to %s/%d\n", argv[1], port);
94 fd = socket(AF_INET, SOCK_STREAM, 0);
96 return error("socket");
98 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
99 return error("connect");
101 signal(SIGINT, show_rate);
102 gettimeofday(&start_time, NULL);
105 ret = splice(STDIN_FILENO, NULL, fd, NULL, SPLICE_SIZE, SPLICE_F_NONBLOCK);
107 if (errno == EAGAIN) {
111 return error("splice");
115 kb_sent += ret >> 10;