FD.io VPP  v19.04.1-1-ge4a0f9f
Vector Packet Processing
socket_echo_client.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netdb.h>
21 #include <vppinfra/format.h>
22 #include <sys/time.h>
23 
24 int
25 main (int argc, char *argv[])
26 {
27  int sockfd, portno, n;
28  struct sockaddr_in serv_addr;
29  struct hostent *server;
30  u8 *rx_buffer = 0, *tx_buffer = 0, no_echo = 0, test_bytes = 0;
31  u32 offset;
32  long bytes = 1 << 20, to_send;
33  int i;
34  struct timeval start, end;
35  double deltat;
36 
37  if (argc >= 3)
38  {
39  portno = atoi (argv[2]);
40  server = gethostbyname (argv[1]);
41  if (server == NULL)
42  {
43  clib_unix_warning ("gethostbyname");
44  exit (1);
45  }
46 
47  argc -= 3;
48  argv += 3;
49 
50  if (argc)
51  {
52  bytes = ((long) atoi (argv[0])) << 20;
53  argc--;
54  argv++;
55  }
56  if (argc)
57  {
58  no_echo = atoi (argv[0]);
59  argc--;
60  argv++;
61  }
62  if (argc)
63  {
64  test_bytes = atoi (argv[0]);
65  argc--;
66  argv++;
67  }
68  }
69  else
70  {
71  portno = 1234; // atoi(argv[2]);
72  server = gethostbyname ("6.0.1.1" /* argv[1] */ );
73  if (server == NULL)
74  {
75  clib_unix_warning ("gethostbyname");
76  exit (1);
77  }
78  }
79 
80  to_send = bytes;
81  sockfd = socket (AF_INET, SOCK_STREAM, 0);
82  if (sockfd < 0)
83  {
84  clib_unix_error ("socket");
85  exit (1);
86  }
87 
88  bzero ((char *) &serv_addr, sizeof (serv_addr));
89  serv_addr.sin_family = AF_INET;
90  bcopy ((char *) server->h_addr,
91  (char *) &serv_addr.sin_addr.s_addr, server->h_length);
92  serv_addr.sin_port = htons (portno);
93  if (connect (sockfd, (const void *) &serv_addr, sizeof (serv_addr)) < 0)
94  {
95  clib_unix_warning ("connect");
96  exit (1);
97  }
98 
99  vec_validate (rx_buffer, 128 << 10);
100  vec_validate (tx_buffer, 128 << 10);
101 
102  for (i = 0; i < vec_len (tx_buffer); i++)
103  tx_buffer[i] = (i + 1) % 0xff;
104 
105  /*
106  * Send one packet to warm up the RX pipeline
107  */
108  n = send (sockfd, tx_buffer, vec_len (tx_buffer), 0 /* flags */ );
109  if (n != vec_len (tx_buffer))
110  {
111  clib_unix_warning ("write");
112  exit (0);
113  }
114 
115  gettimeofday (&start, NULL);
116  while (bytes > 0)
117  {
118  /*
119  * TX
120  */
121  n = send (sockfd, tx_buffer, vec_len (tx_buffer), 0 /* flags */ );
122  if (n != vec_len (tx_buffer))
123  {
124  clib_unix_warning ("write");
125  exit (0);
126  }
127  bytes -= n;
128 
129  if (no_echo)
130  continue;
131 
132  /*
133  * RX
134  */
135 
136  offset = 0;
137  do
138  {
139  n = recv (sockfd, rx_buffer + offset,
140  vec_len (rx_buffer) - offset, 0 /* flags */ );
141  if (n < 0)
142  {
143  clib_unix_warning ("read");
144  exit (0);
145  }
146  offset += n;
147  }
148  while (offset < vec_len (rx_buffer));
149 
150  if (test_bytes)
151  {
152  for (i = 0; i < vec_len (rx_buffer); i++)
153  {
154  if (rx_buffer[i] != tx_buffer[i])
155  {
156  clib_warning ("[%d] read 0x%x not 0x%x", rx_buffer[i],
157  tx_buffer[i]);
158  exit (1);
159  }
160  }
161  }
162  }
163  close (sockfd);
164  gettimeofday (&end, NULL);
165 
166  deltat = (end.tv_sec - start.tv_sec);
167  deltat += (end.tv_usec - start.tv_usec) / 1000000.0; // us to ms
168  clib_warning ("Finished in %.6f", deltat);
169  clib_warning ("%.4f Gbit/second %s", (((f64) to_send * 8.0) / deltat / 1e9),
170  no_echo ? "half" : "full");
171  return 0;
172 }
173 
174 
175 /*
176  * fd.io coding-style-patch-verification: ON
177  *
178  * Local Variables:
179  * eval: (c-set-style "gnu")
180  * End:
181  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
#define NULL
Definition: clib.h:58
int i
unsigned char u8
Definition: types.h:56
#define clib_unix_error(format, args...)
Definition: error.h:65
double f64
Definition: types.h:142
static clib_error_t * tx_buffer(void *transport, mc_transport_type_t type, u32 buffer_index)
Definition: mc_socket.c:129
unsigned int u32
Definition: types.h:88
void test_bytes(echo_server_main_t *esm, int actual_transfer)
Definition: echo_server.c:118
#define clib_warning(format, args...)
Definition: error.h:59
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define clib_unix_warning(format, args...)
Definition: error.h:68
struct clib_bihash_value offset
template key/value backing page structure
int main(int argc, char *argv[])