windows下实现ipv6 客户端批量登录

一个简易的win下的ipv6 socket编程,读取配置文件,创建线程,连接服务器,用于测试多并发情况下服务器运行状况

login.c

#include<stdio.h>
#include<stdlib.h>
#include <windows.h>          // for HANDLE
//#include<pthread.h>
#include<string.h>
#include <time.h>
//#include<netinet/in.h>
//#include<sys/types.h>
//#include<sys/socket.h>
#define STACK_SIZE 64*1024
#pragma pack(1)
#include "login.h"
FILE * fp2=NULL;

void *loginthread( void * arg )
{
	USER_INFO *user = (USER_INFO *)arg;
    connect_server_ipv6(user);
	free(arg);
	
	return ((void *) 1);
}

int main(void)
{
    FILE * fp = NULL;

    char info[272] = "";
    USER_INFO *pinfo;

    HANDLE hThread;
    DWORD IDThread;
    char buf[128];
    //pthread_t pid;
    int n = 0;

    time_t rawtime;
    struct tm * timeinfo;

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );

    //printf ( "\007The current date/time is: %s", asctime (timeinfo) );
    memset(buf, 0, sizeof(buf));
    strftime(buf, 80, "begintime:%I:%M:%S\n", timeinfo);
    printf("begintime:%s", buf);

    fp2=fopen("time.txt","w+");
    if(NULL==fp2)
    {
        return-1;
    }

    fwrite ( buf, strlen(buf), 1 , fp2 );


    fp = fopen( "user.txt" , "r" );
    if( fp == NULL ) return -1;

    while( fgets( info, 63, fp ) != NULL )
    {
        if (n == 100)
            break;

        pinfo = ( USER_INFO * )malloc( sizeof( USER_INFO ) );
        memset( pinfo, 0, sizeof( USER_INFO ) );
        sscanf( info, "%s%s", pinfo->username, pinfo->password );

        //printf("username:%s password:%s\n", pinfo->username, pinfo->password);

        hThread = CreateThread(NULL, STACK_SIZE, (LPTHREAD_START_ROUTINE)loginthread, ( void * )pinfo, // pass config 
                               STACK_SIZE_PARAM_IS_A_RESERVATION, &IDThread);
        if (hThread == NULL)
        {
            printf("Create Thread failed:n:%d\n", n);
            return -1;
        }

        n++;
        //pthread_create( &pid, NULL, loginthread, ( void * )pinfo );
    }
    printf("%d",n);
#if 0
    memset(buf, 0, sizeof(buf));
    sprintf(buf, "%s",asctime (timeinfo));
    fwrite ( buf, sizeof(buf), 1 , fp2 );
#endif

    getchar();
    CloseHandle(hThread);
    return 0;
}

login.h

#ifndef __LOGIN_H__
#define __LOGIN_H__
#pragma pack(1)

typedef struct
{
    char username[256];
    char password[16];
} USER_INFO;


struct tcp_keepalive
{
    ULONG onoff;
    ULONG keepalivetime;
    ULONG keepaliveinterval;
};

int connect_server_ipv6(USER_INFO *user);
#endif //__LOGIN_H__

 

win32client_ipv6.c

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <IPHlpApi.h>

#include <stdio.h>
#include <errno.h>

#include <time.h>

extern FILE * fp2;

#pragma comment(lib,"ws2_32.lib")
#include "login.h"
#define NS_INT16SZ   2

#define NO_FLAGS_SET 0
#define IPV6_SERVADDR "::1"
#define IPV6_PORT 2000
#define MAXDATASIZE 200

#define NS_INADDRSZ      4
#define NS_IN6ADDRSZ    16

#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)

int inet_pton4(const char *src, unsigned char *dst)
{
    static const char digits[] = "0123456789";
    int saw_digit, octets, ch;
    unsigned char tmp[NS_INADDRSZ], *tp;
    saw_digit = 0;
    octets = 0;
    *(tp = tmp) = 0;
    while ((ch = *src++) != '\0')
    {
        const char *pch;
        if ((pch = strchr(digits, ch)) != NULL)
        {
            unsigned int new = *tp * 10 + (pch - digits);
            if (new > 255)
                return (0);
            *tp = new;
            if (! saw_digit)
            {
                if (++octets > 4)
                    return (0);
                saw_digit = 1;
            }
        }
        else if (ch == '.' && saw_digit)
        {
            if (octets == 4)
                return (0);
            *++tp = 0;
            saw_digit = 0;
        }
        else
            return (0);
    }
    if (octets < 4)
        return (0);
    memcpy(dst, tmp, NS_INADDRSZ);
    return (1);
}
int inet_pton6(const char *src, unsigned char *dst)
{
    static const char xdigits_l[] = "0123456789abcdef",
                                    xdigits_u[] = "0123456789ABCDEF";
    unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
    const char *xdigits, *curtok;
    int ch, saw_xdigit;
    unsigned int val;
    memset((tp = tmp), '\0', NS_IN6ADDRSZ);
    endp = tp + NS_IN6ADDRSZ;
    colonp = NULL;
    /* Leading :: requires some special handling. */
    if (*src == ':')
        if (*++src != ':')
            return (0);
    curtok = src;
    saw_xdigit = 0;
    val = 0;
    while ((ch = *src++) != '\0')
    {
        const char *pch;
        if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
            pch = strchr((xdigits = xdigits_u), ch);
        if (pch != NULL)
        {
            val <<= 4;
            val |= (pch - xdigits);
            if (val > 0xffff)
                return (0);
            saw_xdigit = 1;
            continue;
        }
        if (ch == ':')
        {
            curtok = src;
            if (!saw_xdigit)
            {
                if (colonp)
                    return (0);
                colonp = tp;
                continue;
            }
            if (tp + NS_INT16SZ > endp)
                return (0);
            *tp++ = (unsigned char) (val >> 8) & 0xff;
            *tp++ = (unsigned char) val & 0xff;
            saw_xdigit = 0;
            val = 0;
            continue;
        }
        if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&    inet_pton4(curtok, tp) > 0)
        {
            tp += NS_INADDRSZ;
            saw_xdigit = 0;
            break;  /* '\0' was seen by inet_pton4(). */
        }
        return (0);
    }
    if (saw_xdigit)
    {
        if (tp + NS_INT16SZ > endp)
            return (0);
        *tp++ = (unsigned char) (val >> 8) & 0xff;
        *tp++ = (unsigned char) val & 0xff;
    }
    if (colonp != NULL)
    {
        /*                 * Since some memmove()'s erroneously fail to handle                 * overlapping regions, we'll do the shift by hand.                 */
        const int n = tp - colonp;
        int i;
        for (i = 1; i <= n; i++)
        {
            endp[- i] = colonp[n - i];
            colonp[n - i] = 0;
        }
        tp = endp;
    }
    if (tp != endp)
        return (0);
    memcpy(dst, tmp, NS_IN6ADDRSZ);
    return (1);
}

void keepalive(int sfd)
{
    ssize_t n;

    char keepalivemessage[5];

    memset(keepalivemessage, 0, sizeof(keepalivemessage));
    keepalivemessage[0] = 0x3;
    *((int *)&keepalivemessage[1]) = htonl(5);


    n = send(sfd, keepalivemessage, 5, 0);
    // FIXME: check return value.
    //ssize_t write(int listening_socket, const void *buf, size_t count);
    if (n < 0)
    {
        // failed
    }
    else
    {
#ifdef DEBUG
        fprintf(stdout,
                "[%d]Heartbeat Send %ld bytes back, fd:%d.\n",
                getpid(), n, fd);
#endif
    }
}
int connect_server_ipv6(USER_INFO *user)
{
    WSADATA Data;
    SOCKADDR_IN6 destSockAddr;
    SOCKET destSocket;
    unsigned long destAddr;
    int status;
    int recvbytes;
    char str[MAXDATASIZE];
    char tempbuf[MAXDATASIZE];
    char buf[128];
    int lenstr;

    time_t rawtime;
    struct tm * timeinfo;

    /* initialize the Windows Socket DLL */
    status = WSAStartup(MAKEWORD(1, 1), &Data);
    if (status != 0)
        printf("ERROR: WSAStartup unsuccessful\n");

    /* create a socket */
    destSocket = socket(AF_INET6, SOCK_STREAM, 0);
    if (destSocket == INVALID_SOCKET)
    {
        printf("ERROR: socket unsuccessful\n");
        status = WSACleanup();
        if (status == SOCKET_ERROR)
            printf("ERROR: WSACleanup unsuccessful\n");
        return (1);
    }
    int keepAlive = 1; 	 // 开启keepalive属性. 缺省值: 0(关闭)
    setsockopt(destSocket, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));

    struct tcp_keepalive keepin;
    struct tcp_keepalive keepout;
    keepin.keepaliveinterval=5000;//3000;//15s没有数据就开始发送探测包
    keepin.keepalivetime=25000;//15000;//每隔30s发送一次探测包,发10次(默认)
    keepin.onoff=1;

    DWORD dwActualBytesReturned = 0;
    WSAIoctl(destSocket,SIO_KEEPALIVE_VALS,&keepin,sizeof(keepin),&keepout,sizeof(keepout),&dwActualBytesReturned,NULL,NULL);

    /*memset destSockAddr*/
    memset(&destSockAddr, 0, sizeof(SOCKADDR_IN6));

    /* specify the address family as Internet */
    destSockAddr.sin6_family = AF_INET6;

    /* specify the port portion of the address */
    destSockAddr.sin6_port = htons(IPV6_PORT);
    /* addr */
    inet_pton6(IPV6_SERVADDR, (char *)&destSockAddr.sin6_addr);

    //printf("Trying to connect to IPv6 Address: %s\n", IPV6_SERVADDR);
    /* connect to the server */
    status = connect(destSocket, (SOCKADDR *) & destSockAddr, sizeof(destSockAddr));
    if (status == SOCKET_ERROR)
    {
        printf("ERROR: connect unsuccessful\n");
        status = closesocket(destSocket);
        if (status == SOCKET_ERROR)
            printf("ERROR: closesocket unsuccessful\n");
        status = WSACleanup();
        if (status == SOCKET_ERROR)
            printf("ERROR: WSACleanup unsuccessful\n");
        return (1);
    }
    printf("Connected...\n");

    if (send(destSocket, (char *)user, sizeof(USER_INFO), 0) == -1) //发送
    {
        printf("send wrong !\n");
        close(destSocket);
        return 1;
    }
    fprintf(stdout, "send:%d bytes\n", sizeof(USER_INFO));

    for (;;)
    {
        recvbytes = recv(destSocket, str, MAXDATASIZE, 0); //接收
        if (recvbytes < 0)
        {
            {
                printf("recv wrong !\n");
                break;
            }
        }
        else if (recvbytes == 0)
        {
            fprintf(stdout, "%s\n", "recvbytes=0");
            break;
        }
        else
        {
            str[recvbytes] = '\0';
            fprintf(stdout, "received: %d bytes\n", recvbytes);

            /* keepalive */
            //keepalive(destSocket);
        }
    }
    close(destSocket);
	return 0;
}

Makefile

# This makefile builds client_ipv6 using the mingw environment.

EXE =  ipv6_login_client.exe

HEADERS = login.h

OBJS =	win32client_ipv6.o login.o

WARNS = -W -Wall

CC = gcc
CFLAGS = -g -O2 ${WARNS} 


all : ${OBJS}
	${CC} -o ${EXE} ${OBJS}  -lwsock32 -lws2_32

clean :
	rm -f *.o *.exe *.bak

%.o : %.c ${HEADERS}
	${CC}  -c $< -o $@

编译需要在win下面的mingw环境中,需要在当前目录下新建user.txt,格式如下

xiaoming  123
xiaowang  abc  
xiaoli    hello 
xiaoping  666  

然后运行编译生成的ipv6_login_client.exe和服务端相连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值