|
发表于 2017-12-27 11:50:57
只看该作者
板凳
测试程序 Server
/* net-test-server.c
* gcc -o net-test-server net-test-server.c
*/
#ifdef _WIN32
#include <Winsock2.h>
#include <mstcpip.h>
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <time.h>
#include <errno.h>
#endif
#define TEST_TCP_PORT 5495
#define DATA_SIZE_MAX (1024*1024)
#ifndef _WIN32
typedef int SOCKET;
#endif
#ifdef _MSC_VER
#pragma comment (lib, "Ws2_32.lib")
#ifndef int64_t
typedef __int64 int64_t;
#endif
#ifndef int32_t
typedef int int32_t;
#endif
#ifndef uint8_t
typedef unsigned char uint8_t;
#endif
#endif //_MSC_VER
static SOCKET g_listen_sock, g_sock;
static void *g_pBuf = NULL;
static void set_keepalive(SOCKET sock)
{
const int one = 1;
#ifdef _WIN32
struct tcp_keepalive alive_in, alive_out;
unsigned long unused = 0;
alive_in.keepalivetime = 1000; // 1s
alive_in.keepaliveinterval = 1000; //1s
alive_in.onoff = TRUE;
WSAIoctl(sock, SIO_KEEPALIVE_VALS, &alive_in, sizeof(alive_in),
&alive_out, sizeof(alive_out), &unused, NULL, NULL);
#else
int keepalive = 1, keepidle = 2, keepinterval = 1, keepcount = 3;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive));
setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle));
setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval));
setsockopt(sock, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount));
#endif
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&one, sizeof(one));
}
static int read_sock(SOCKET sock, char *buff, int bufflen, int flags)
{
int n;
while (bufflen > 0)
{
n = recv(sock, buff, bufflen, flags);
if (n > 0)
{
buff += n;
bufflen -= n;
}
else if (n == 0) return(0);
#ifdef _WIN32
else if (errno != WSAEWOULDBLOCK)
#else
else if (errno != EAGAIN && errno != EWOULDBLOCK)
#endif
{
return(0);
}
}
return(1);
}
int init_application()
{
int one = 1;
struct sockaddr_in addr;
#ifdef _WIN32
WORD wVersionRequested = MAKEWORD(2, 0);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0) return(0);
srand(GetTickCount());
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
srand(ts.tv_nsec / 1000);
#endif
g_pBuf = malloc(DATA_SIZE_MAX);
if(!g_pBuf) return(0);
memset(g_pBuf, 0, DATA_SIZE_MAX);
g_listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (g_listen_sock == -1) return(0);
/* re-use */
setsockopt(g_listen_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
addr.sin_family = AF_INET;
addr.sin_port = htons(TEST_TCP_PORT);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(g_listen_sock, (struct sockaddr *)&addr, sizeof(addr))) return(0);
if(listen(g_listen_sock, 5)) return(0);
return(1);
}
int main()
{
unsigned char msg;
const int one = 1;
if(!init_application())
{
printf("init app error\n");
return(1);
}
printf("listen ...\n");
g_sock = accept(g_listen_sock, NULL, NULL);
if(g_sock == -1)
{
printf("accept fail\n");
return(1);
}
/* no delay */
setsockopt(g_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
/* keep alive */
set_keepalive(g_sock);
printf("transceiving data ...\n");
while(1)
{
int32_t size;
size = (int32_t)((int64_t)rand() * DATA_SIZE_MAX / RAND_MAX);
if(size > DATA_SIZE_MAX) continue;
/* receive msg */
if(!read_sock(g_sock, (char*)&msg, sizeof(msg), 0)) break;
/* send data size */
if(send(g_sock, (char*)&size, sizeof(size), 0) != sizeof(size)) break;
/* send data */
if(send(g_sock, (char*)g_pBuf, size, 0) != size) break;
}
printf("connection lost\n");
return(1);
}
|
|