source: benchmark/io/sendfile/consumer.c@ bd72c284

ADT ast-experimental
Last change on this file since bd72c284 was 6dc17a3d, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Changed consumer to run for ever.

  • Property mode set to 100644
File size: 3.6 KB
Line 
1// Simple sink program that opens a tcp socket on a random port
2// and then reads everything the socket has to write and then ends.
3
4#define _GNU_SOURCE
5
6#include <stdint.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include <errno.h>
12#include <time.h>
13#include <unistd.h>
14
15#include <sys/socket.h>
16#include <netinet/in.h>
17
18enum {
19 USAGE_ERROR = 1,
20 SOCKET_ERROR,
21 BIND_INUSE,
22 BIND_ERROR,
23 GETNAME_ERROR,
24 LISTEN_ERROR,
25 ACCEPT_ERROR,
26 READ_ERROR
27};
28
29enum { buffer_len = 10240 };
30char buffer[buffer_len];
31
32enum { TIMEGRAN = 1000000000LL };
33
34int main(int argc, char * argv[]) {
35 int port = 0;
36 switch(argc) {
37 case 1: break;
38 case 2:
39 {
40 const char * const str = argv[1];
41 char* endptr;
42 unsigned long long ret = strtoul(str, &endptr, 10);
43 if('\0' != *endptr) { fprintf( stderr, "Invalid argument \"%s\" (not a number)\n", str ); goto USAGE;}
44 if(errno == ERANGE || ret > 65535) { fprintf( stderr, "Invalid argument \"%s\" (value too large)\n", str ); goto USAGE;}
45
46 port = ret;
47 break;
48 }
49 USAGE:
50 default:
51 fprintf( stderr, "USAGE: %s [port]\n", argv[0] );
52 exit( USAGE_ERROR );
53 }
54
55 printf( "%d: Listening on port %d\n", getpid(), port );
56 int listenfd = socket(AF_INET, SOCK_STREAM, 0);
57 if(listenfd < 0) {
58 fprintf( stderr, "socket error: (%d) %s\n", (int)errno, strerror(errno) );
59 exit( SOCKET_ERROR );
60 }
61
62 int ret = 0;
63 struct sockaddr_in address;
64 socklen_t addrlen = sizeof(address);
65 memset( (char *)&address, '\0', addrlen );
66 address.sin_family = AF_INET;
67 address.sin_addr.s_addr = htonl( INADDR_ANY );
68 address.sin_port = htons( port );
69
70 ret = bind( listenfd, (struct sockaddr *) &address, addrlen );
71 if(ret < 0) {
72 if(errno == EADDRINUSE) {
73 fprintf( stderr, "Port already in use in non-interactive mode. Aborting\n" );
74 exit( BIND_INUSE );
75 }
76 fprintf( stderr, "bind error: (%d) %s\n", (int)errno, strerror(errno) );
77 exit( BIND_ERROR );
78 }
79
80 ret = getsockname( listenfd, (struct sockaddr *) &address, &addrlen );
81 if(ret < 0) {
82 fprintf( stderr, "getname error: (%d) %s\n", (int)errno, strerror(errno) );
83 exit(GETNAME_ERROR);
84 }
85
86 printf( "actial port: %d\n", ntohs(address.sin_port) );
87
88 ret = listen( listenfd, 1 );
89 if(ret < 0) {
90 fprintf( stderr, "listen error: (%d) %s\n", (int)errno, strerror(errno) );
91 exit( 5 );
92 }
93
94 for(;;) {
95 struct sockaddr_in cli_addr;
96 __socklen_t clilen = sizeof(cli_addr);
97 int fd = accept( listenfd, (struct sockaddr *) &cli_addr, &clilen );
98 if(fd < 0) {
99 fprintf( stderr, "accept error: (%d) %s\n", (int)errno, strerror(errno) );
100 exit( ACCEPT_ERROR );
101 }
102
103 int error = 0;
104 size_t calls = 0;
105 size_t bytes = 0;
106
107 struct timespec after, before;
108
109 clock_gettime(CLOCK_MONOTONIC, &before);
110
111 for(;;) {
112 ret = recv(fd, buffer, buffer_len, 0);
113 if(ret == 0 ) goto EXIT;
114 if(ret < 0 ) {
115 if( errno == EAGAIN || errno == EWOULDBLOCK) continue;
116 if( errno == ECONNRESET ) { printf("Connection reset\n"); goto EXIT; }
117 if( errno == EPIPE ) { printf("Pipe closed\n"); goto EXIT; }
118 fprintf( stderr, "accept error: (%d) %s\n", (int)errno, strerror(errno) );
119 error = READ_ERROR;
120 goto EXIT;
121 }
122 calls++;
123 bytes += ret;
124 }
125 EXIT:;
126
127 clock_gettime(CLOCK_MONOTONIC, &after);
128
129 uint64_t tb = ((int64_t)before.tv_sec * TIMEGRAN) + before.tv_nsec;
130 uint64_t ta = ((int64_t)after.tv_sec * TIMEGRAN) + after.tv_nsec;
131 double secs = ((double)ta - tb) / TIMEGRAN;
132
133 printf("Received %'zu bytes in %'zu reads, %f seconds\n", bytes, calls, secs);
134 printf(" - %'3.3f bytes per second\n", (((double)bytes) / secs));
135 printf(" - %'3.3f bytes per calls\n", (((double)bytes) / calls));
136
137 close(fd);
138 if(error != 0) exit( error );
139 }
140 close(listenfd);
141 return 0;
142}
Note: See TracBrowser for help on using the repository browser.