Changeset View
Changeset View
Standalone View
Standalone View
tools/tools/mq-testing/tcp/client.c
- This file was added.
/*- | |||||
* Copyright (c) 2015, Tiwei Bie <btw@FreeBSD.org> | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice unmodified, this list of conditions, and the following | |||||
* disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include <getopt.h> | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <signal.h> | |||||
#include "lwip/tcpip.h" | |||||
#include "lwip/sockets.h" | |||||
#include "vmeif.h" | |||||
#include "common.h" | |||||
static ip_addr_t ipaddr, netmask, gw; | |||||
static char payload[1024]; | |||||
static struct netif netif; | |||||
static int quiet = 0; | |||||
static int nr_connections = 10000; | |||||
static const char *gw_str = "192.168.10.1"; | |||||
static const char *ip_str = "192.168.10.2"; | |||||
static const char *nm_str = "255.255.255.0"; | |||||
/* nonstatic debug cmd option, exported in lwipopts.h */ | |||||
unsigned char debug_flags; | |||||
static void | |||||
usage(const char *prgname) | |||||
{ | |||||
(void)prgname; | |||||
fprintf(stderr, | |||||
"Usage: %s [-g gateway] [-i address] [-m netmask]\n" | |||||
" %*s [-n connections] [-dhq]\n", | |||||
prgname, (int)strlen(prgname), ""); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
static void | |||||
init_netifs(void) | |||||
{ | |||||
netif_set_default(netif_add(&netif, &ipaddr, &netmask, &gw, | |||||
NULL, vmeif_init, tcpip_input)); | |||||
netif_set_up(&netif); | |||||
} | |||||
static void | |||||
tcpip_init_done(void *arg) | |||||
{ | |||||
sys_sem_t *sem = arg; | |||||
init_netifs(); | |||||
sys_sem_signal(sem); | |||||
} | |||||
static void | |||||
client_routine(void) | |||||
{ | |||||
struct sockaddr_in daddr; | |||||
int sd, *sds; | |||||
int i; | |||||
sds = malloc(sizeof(int) * nr_connections); | |||||
memset(&daddr, 0, sizeof(daddr)); | |||||
daddr.sin_family = AF_INET; | |||||
daddr.sin_addr.s_addr = gw.addr; | |||||
daddr.sin_port = htons(SERVER_PORT); | |||||
for (i = 0; i < nr_connections; i++) { | |||||
sd = lwip_socket(AF_INET, SOCK_STREAM, 0); | |||||
if (sd < 0) { | |||||
fprintf(stderr, "Failed to create socket\n"); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
if (lwip_connect(sd, (struct sockaddr *)&daddr, | |||||
sizeof(daddr)) < 0) { | |||||
fprintf(stderr, "Failed to connect to server sd=%d\n", | |||||
i); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
sds[i] = sd; | |||||
} | |||||
while (1) { | |||||
for (i = 0; i < nr_connections; i++) { | |||||
sd = sds[i]; | |||||
snprintf(payload, sizeof(payload), | |||||
"message from socket %d", i); | |||||
if (lwip_send(sd, payload, strlen(payload), 0) < 0) { | |||||
fprintf(stderr, | |||||
"Failed to send data to server\n"); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
static void | |||||
main_thread(void) | |||||
{ | |||||
sys_sem_t sem; | |||||
netif_init(); | |||||
if (sys_sem_new(&sem, 0) != ERR_OK) { | |||||
fprintf(stderr, "Failed to create semaphore\n"); | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
tcpip_init(tcpip_init_done, &sem); | |||||
sys_sem_wait(&sem); | |||||
if (!quiet) | |||||
printf("TCP/IP initialized.\n"); | |||||
client_routine(); | |||||
} | |||||
static void | |||||
signal_handler(int arg) | |||||
{ | |||||
if (arg == SIGINT) | |||||
exit(EXIT_SUCCESS); | |||||
} | |||||
int | |||||
main(int argc, char **argv) | |||||
{ | |||||
int ch; | |||||
debug_flags = LWIP_DBG_OFF; | |||||
while ((ch = getopt(argc, argv, "g:i:m:n:dhq")) != -1) { | |||||
switch (ch) { | |||||
case 'd': | |||||
debug_flags |= | |||||
(LWIP_DBG_ON | LWIP_DBG_TRACE | LWIP_DBG_STATE | | |||||
LWIP_DBG_FRESH | LWIP_DBG_HALT); | |||||
break; | |||||
case 'g': | |||||
gw_str = optarg; | |||||
break; | |||||
case 'i': | |||||
ip_str = optarg; | |||||
break; | |||||
case 'm': | |||||
nm_str = optarg; | |||||
break; | |||||
case 'n': | |||||
sscanf(optarg, "%d", &nr_connections); | |||||
break; | |||||
case 'q': | |||||
quiet = 1; | |||||
break; | |||||
case 'h': | |||||
default: | |||||
usage(argv[0]); | |||||
break; | |||||
} | |||||
} | |||||
gw.addr = inet_addr(gw_str); | |||||
ipaddr.addr = inet_addr(ip_str); | |||||
netmask.addr = inet_addr(nm_str); | |||||
signal(SIGINT, signal_handler); | |||||
if (!quiet) { | |||||
printf("host at %s\n", ip_str); | |||||
printf("netmask: %s\n", nm_str); | |||||
printf("gateway: %s\n", gw_str); | |||||
printf("connections: %d\n", nr_connections); | |||||
} | |||||
main_thread(); | |||||
return (0); | |||||
} |