代码如下
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
struct test_context_s
{
char serverip[16];
int port;
int threadnum;
int connection;
int requestion;
#if 1
int failed;
#endif
};
typedef struct test_context_s test_context_t;
int connected_tcpserver(const char *ip, unsigned short port)
{
int connfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in tcpserver_addr;
memset(&tcpserver_addr, 0, sizeof(struct sockaddr_in));
tcpserver_addr.sin_family = AF_INET;
tcpserver_addr.sin_addr.s_addr = inet_addr(ip);
tcpserver_addr.sin_port = htons(port);
int ret = connect(connfd, (struct sockaddr *)&tcpserver_addr, sizeof(struct sockaddr_in));
if (ret)
{
perror("connect\n");
return -1;
}
return connfd;
}
static void *test_qps_entry(void *arg)
{
test_context_t *pctx = (test_context_t *)arg;
int connfd = connected_tcpserver(pctx->serverip, pctx->port);
if (connfd < 0)
{
printf("connect_tcpserver failed");
return NULL;
}
int count = pctx->requestion / pctx->threadnum;
int i = 0;
while (i++ < count)
{
int ret = send_recv_tcppkt(connfd);
if (ret != 0)
{
printf("send_recv_tcppkt failed!");
pctx->failed++;
continue;
}
}
return NULL;
}
#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
#define TEST_MESSAGE "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz\r\n\0"
#define RBUFFER_LENGTH 128
int send_recv_tcppkt(int fd)
{
int res = send(fd, TEST_MESSAGE, strlen(TEST_MESSAGE), 0);
if (res < 0)
{
exit(1);
}
char rbuffer[RBUFFER_LENGTH] = {0};
recv(fd, rbuffer, RBUFFER_LENGTH, 0);
if (recv <= 0)
{
exit(1);
}
if (strcmp(rbuffer, TEST_MESSAGE) != 0)
{
printf("failed: '%s' != '%s'\n", rbuffer, TEST_MESSAGE);
return -1;
}
return 0;
}
int main(int argc, char *const argv[])
{
int ret = 0;
test_context_t ctx = {0};
int opt;
while ((opt = getopt(argc, argv, "s:p:t:c:n:?")) != -1)
{
switch (opt)
{
case 's':
printf("-s: %s\n", optarg);
strcpy(ctx.serverip, optarg);
break;
case 'p':
printf("-p: %s\n", optarg);
ctx.port = atoi(optarg);
break;
case 't':
printf("-t: %s\n", optarg);
ctx.threadnum = atoi(optarg);
break;
case 'c':
printf("-c: %s\n", optarg);
ctx.connection = atoi(optarg);
break;
case 'n':
printf("-n: %s\n", optarg);
ctx.requestion = atoi(optarg);
break;
default:
return -1;
}
}
pthread_t *ptid = malloc(ctx.threadnum * sizeof(pthread_t));
int i = 0;
struct timeval tv_begin;
gettimeofday(&tv_begin, NULL);
for (i = 0; i < ctx.threadnum; i++)
{
pthread_create(&ptid[i], NULL, test_qps_entry, &ctx);
}
for (i = 0; i < ctx.threadnum; i++)
{
pthread_join(ptid[i], NULL);
}
struct timeval tv_end;
gettimeofday(&tv_end, NULL);
int time_used = TIME_SUB_MS(tv_end, tv_begin);
printf("success: %d, failed: %d\n, time_used: %d\n", ctx.requestion-ctx.failed, ctx.failed, time_used);
clean:
free(ptid);
return ret;
}