Apache HTTPD
sockperf.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* sockperf.c
18 * This simple network client tries to connect to an echo daemon (echod)
19 * listening on a port it supplies, then time how long it takes to
20 * reply with packets of varying sizes.
21 * It prints results once completed.
22 *
23 * To run,
24 *
25 * ./echod &
26 * ./sockperf
27 */
28
29#include <stdio.h>
30#include <stdlib.h> /* for atexit() */
31
32#include "apr.h"
33#include "apr_network_io.h"
34#include "apr_strings.h"
35
36#define MAX_ITERS 10
37#define TEST_SIZE 1024
38
39struct testSet {
40 char c;
42 int iters;
43} testRuns[] = {
44 { 'a', 1, 3 },
45 { 'b', 4, 3 },
46 { 'c', 16, 5 },
47 { 'd', 64, 5 },
48 { 'e', 256, 10 },
49};
50
57
58static apr_int16_t testPort = 4747;
60
61static void reportError(const char *msg, apr_status_t rv,
63{
64 fprintf(stderr, "%s\n", msg);
65 if (rv != APR_SUCCESS)
66 fprintf(stderr, "Error: %d\n'%s'\n", rv,
67 apr_psprintf(pool, "%pm", &rv));
68
69}
70
76
79{
81 apr_status_t rv;
83 char *recvBuf;
85 int i;
86
87 if (! sockAddr) {
88 rv = apr_sockaddr_info_get(&sockAddr, "127.0.0.1", APR_UNSPEC,
89 testPort, 0, pool);
90 if (rv != APR_SUCCESS) {
91 reportError("Unable to get socket info", rv, pool);
92 return rv;
93 }
94
95 /* make sure we can connect to daemon before we try tests */
96
98 pool);
99 if (rv != APR_SUCCESS) {
100 reportError("Unable to create IPv4 stream socket", rv, pool);
101 return rv;
102 }
103
105 if (rv != APR_SUCCESS) {
106 reportError("Unable to connect to echod!", rv, pool);
108 return rv;
109 }
111
112 }
113
115 if (! recvBuf) {
116 reportError("Unable to allocate buffer", ENOMEM, pool);
117 return ENOMEM;
118 }
119
120 *t = 0;
121
122 /* START! */
125 pool);
126 if (rv != APR_SUCCESS) {
127 reportError("Unable to create IPv4 stream socket", rv, pool);
128 return rv;
129 }
130
132 if (rv != APR_SUCCESS) {
133 reportError("Unable to connect to echod!", rv, pool);
135 return rv;
136 }
137
138 for (i = 0; i < 3; i++) {
139
140 len = size;
141 thistime = size;
142
143 rv = apr_socket_send(sock, buf, &len);
144 if (rv != APR_SUCCESS || len != size) {
146 "Unable to send data correctly (iteration %d of 3)",
147 i) , rv, pool);
150 return rv;
151 }
152
153 do {
154 len = thistime;
156 if (rv != APR_SUCCESS) {
157 reportError("Error receiving from socket", rv, pool);
158 break;
159 }
160 thistime -= len;
161 } while (thistime);
162 }
163
167 /* STOP! */
168
169 if (thistime) {
170 reportError("Received less than we sent :-(", rv, pool);
171 return rv;
172 }
173 if (strncmp(recvBuf, buf, size) != 0) {
174 reportError("Received corrupt data :-(", 0, pool);
175 printf("We sent:\n%s\nWe received:\n%s\n", buf, recvBuf);
176 return EINVAL;
177 }
178 *t = testEnd - testStart;
179 return APR_SUCCESS;
180}
181
182static apr_status_t runTest(struct testSet *ts, struct testResult *res,
184{
185 char *buffer;
187 int i;
188 apr_size_t sz = ts->size * TEST_SIZE;
189
191 if (!buffer) {
192 reportError("Unable to allocate buffer", ENOMEM, pool);
193 return ENOMEM;
194 }
195 memset(buffer, ts->c, sz);
196
197 res->iters = ts->iters > MAX_ITERS ? MAX_ITERS : ts->iters;
198
199 for (i = 0; i < res->iters; i++) {
202 if (rv != APR_SUCCESS) {
203 res->iters = i;
204 break;
205 }
206 res->msecs[i] = iterTime;
207 }
208
209 return rv;
210}
211
212int main(int argc, char **argv)
213{
215 apr_status_t rv;
216 int i;
217 int nTests = sizeof(testRuns) / sizeof(testRuns[0]);
218 struct testResult *results;
219
220 printf("APR Test Application: sockperf\n");
221
224
226
227 results = (struct testResult *)apr_pcalloc(pool,
228 sizeof(*results) * nTests);
229
230 for (i = 0; i < nTests; i++) {
231 printf("Test -> %c\n", testRuns[i].c);
232 results[i].size = testRuns[i].size * (apr_size_t)TEST_SIZE;
233 rv = runTest(&testRuns[i], &results[i], pool);
234 if (rv != APR_SUCCESS) {
235 /* error already reported */
236 exit(1);
237 }
238 }
239
240 printf("Tests Complete!\n");
241 for (i = 0; i < nTests; i++) {
242 int j;
244 printf("%10d byte block:\n", results[i].size);
245 printf("\t%2d iterations : ", results[i].iters);
246 for (j = 0; j < results[i].iters; j++) {
247 printf("%6" APR_TIME_T_FMT, results[i].msecs[j]);
248 totTime += results[i].msecs[j];
249 }
250 printf("<\n");
251 printf("\t Average: %6" APR_TIME_T_FMT "\n",
252 totTime / results[i].iters);
253 }
254
255 return 0;
256}
const char apr_size_t len
Definition ap_regex.h:187
APR Network library.
APR Strings library.
const unsigned char * buf
Definition util_md5.h:50
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
#define APR_PROTO_TCP
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
char * buffer
apr_pool_t int argc
Definition apr_getopt.h:104
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_socket_t * sock
apr_interval_time_t t
#define APR_UNSPEC
#define APR_INET
#define apr_pool_create(newpool, parent)
Definition apr_pools.h:322
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
#define APR_TIME_T_FMT
Definition apr_time.h:52
apr_int64_t apr_time_t
Definition apr_time.h:45
const char * argv[3]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
int main(void)
Definition occhild.c:9
#define MAX_ITERS
Definition sockperf.c:36
static apr_status_t runTest(struct testSet *ts, struct testResult *res, apr_pool_t *pool)
Definition sockperf.c:182
static apr_sockaddr_t * sockAddr
Definition sockperf.c:59
static void reportError(const char *msg, apr_status_t rv, apr_pool_t *pool)
Definition sockperf.c:61
static apr_status_t sendRecvBuffer(apr_time_t *t, const char *buf, apr_size_t size, apr_pool_t *pool)
Definition sockperf.c:77
static apr_int16_t testPort
Definition sockperf.c:58
#define TEST_SIZE
Definition sockperf.c:37
static void closeConnection(apr_socket_t *sock)
Definition sockperf.c:71
struct testSet testRuns[]
apr_time_t avg
Definition sockperf.c:55
int iters
Definition sockperf.c:53
apr_time_t msecs[10]
Definition sockperf.c:54
char c
Definition sockperf.c:40
apr_size_t size
Definition sockperf.c:41
int iters
Definition sockperf.c:42
apr_status_t apr_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
Definition sendrecv.c:30
apr_status_t apr_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
Definition sendrecv.c:70
apr_status_t apr_socket_close(apr_socket_t *thesocket)
Definition sockets.c:211
apr_status_t apr_socket_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
Definition sockets.c:388
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont)
Definition sockets.c:116