#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <windows.h>
typedef
BOOL
(PASCAL FAR * LPFN_CONNECTEX) (
IN SOCKET s,
IN const struct sockaddr FAR *name,
IN int namelen,
IN PVOID lpSendBuffer OPTIONAL,
IN DWORD dwSendDataLength,
OUT LPDWORD lpdwBytesSent,
IN LPOVERLAPPED lpOverlapped
);
#define WSAID_CONNECTEX \
{0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
// >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>>
char* g_pIP[64] = {0};
SOCKET g_skts[64] = {0};
HANDLE g_hEventsConn[64] = {0};
//OVERLAPPED g_olConn = {0};
char g_bufErr1[1024] = {0};
char g_bufErr2[1024] = {0};
LPFN_CONNECTEX g_lpConnectEx = NULL;
GUID g_GuidConnectEx = WSAID_CONNECTEX; // The Guid
// <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<< <<<<<
#include <time.h>
int g_iRand = 0;
void zcGetIP()
{
// 设置 64 个ip
g_pIP[0] = new char[16];
strcpy(g_pIP[0], "220.181.111.147"); // baidu
for(int i=1; i<63; i++)
{
g_pIP[i] = new char[16];
sprintf(g_pIP[i], "192.168.3.%d", i+100);
}
g_pIP[64] = new char[16];
strcpy(g_pIP[64], "74.125.71.147"); // google
// 初始化 64 skt 为 -1
for(i=0; i<64; i++)
{ g_skts[i] = INVALID_SOCKET; }
// 初始化 event 事件
for(i=0; i<64; i++)
{ g_hEventsConn[i] = WSACreateEvent(); }
/*
for(i=0; i<64; i++)
{
printf("%s ==> %d\n", g_pIP[i], g_skts[i]);
} //*/
srand((unsigned)time(0));
g_iRand = rand();
char szFileName[MAX_PATH] = {0};
::GetModuleFileName(0, szFileName, MAX_PATH);
char bufDate[32] = {0};
sprintf(bufDate, "__%08X.txt", g_iRand);
strcat(szFileName, bufDate);
printf("%s\n", szFileName);
}
// 线程过程
DWORD WINAPI ThreadProc(LPVOID _lpParameter)
{
DWORD dwThreadID = ::GetCurrentThreadId();
while (1)
{
DWORD dwErr = 0;
__try
{
DWORD dwIdx = WSAWaitForMultipleEvents(
64, // 一共等待几个事件
&g_hEventsConn[0],//第一个事件的指针(事件是按照数组来放置的)
false, // 是否等到所有事件都受信才返回
WSA_INFINITE,// 等待的时间
false);
if (dwIdx != WSA_WAIT_FAILED)
{
dwIdx = dwIdx - WSA_WAIT_EVENT_0;
for (DWORD dw=0; dw<=dwIdx; dw++) // 一定要注意啊!! 这里是 "dw<=dwIdx" ,并不是 "dw<dwIdx" !!!
{
DWORD dwIdx1 = WSAWaitForMultipleEvents(1, &g_hEventsConn[dw], true, 0, false);
if ((dwIdx1 != WSA_WAIT_TIMEOUT)&&(dwIdx1 != WSA_WAIT_FAILED))
{
WSANETWORKEVENTS event = {0};
if (SOCKET_ERROR == WSAEnumNetworkEvents(
g_skts[dw],
g_hEventsConn[dw],
&event))
{
/* int iErr = WSAGetLastError();
sprintf(buf, "WsaEnumNetworkEvents(%d) SOCKET_ERROR : %X", dw, iErr);
zcPrintErr2(&buf[0]);
*/
// 没操作完就关闭 socket,事件没有重置,so需要手动重置,不然WsaEnumNetworkEvents一直出错,循环一直进行
WSAResetEvent(g_hEventsConn[dw]);
}
else
{
if ((event.lNetworkEvents & FD_CONNECT) != 0)
{
int iErrCode = event.iErrorCode[FD_CONNECT_BIT];
if (0 == iErrCode) // FD_CONNECT 没错误 {或者 是 10048}
{
printf("{%d}ConnectEx back : %d\n", dwThreadID, dw);
}
else
{
printf("{%d}ConnectEx(%d) err : %d\n", dwThreadID, dw, iErrCode);
}
}
}
}
}
}
}
__except(dwErr = GetExceptionCode())
{
// EXCEPTION_ACCESS_VIOLATION
printf("sub thread while exception : %X", dwErr);
}
}
return 0;
}
void zcPrintErr1(char* _p)
{
memset(&g_bufErr1[0], 0, sizeof(g_bufErr1));
SYSTEMTIME nowTime;
GetLocalTime(&nowTime);
sprintf(g_bufErr1, "%4d-%02d-%02d %02d:%02d:%02d.%03d %s",
nowTime.wYear, nowTime.wMonth, nowTime.wDay,
nowTime.wHour, nowTime.wMinute, nowTime.wSecond, nowTime.wMilliseconds,
_p);
printf("%s\n", g_bufErr1);
// *** ***
// 写文件
char szFileName[MAX_PATH] = {0};
::GetModuleFileName(0, szFileName, MAX_PATH);
char bufDate[32] = {0};
sprintf(bufDate, "__%08X.txt", g_iRand);
strcat(szFileName, bufDate);
printf("%s\n", szFileName);
HANDLE hFile = CreateFile(
szFileName,
// "C:\\zcTCP_Err.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
printf("%4d-%02d-%02d %02d:%02d:%02d.%03d CreateFile INVALID_HANDLE_VALUE : %d\n", GetLastError());
return;
}
SetFilePointer(hFile,0,NULL,FILE_END);
int iLen = strlen(g_bufErr1);
g_bufErr1[iLen] = 0x0D;
g_bufErr1[iLen+1] = 0x0A;
g_bufErr1[iLen+2] = 0;
DWORD dwWritten = 0;
if (0 == WriteFile(hFile, g_bufErr1, iLen+2, &dwWritten, NULL))
{
printf("WriteFile err : %d\n", GetLastError());
::CloseHandle(hFile);
return;
}
if (dwWritten != ((DWORD)(iLen+2)))
{
printf("WriteFile 'dwWritten != iLen+2' : %d\n", GetLastError());
::CloseHandle(hFile);
return;
}
::CloseHandle(hFile);
}
// TCP 连接操作
void zcTcpConn(int _iIdx)
{
char bufErr[128] = {0};
// 关闭 socket
if (g_skts[_iIdx] != INVALID_SOCKET)
{
linger l = {0};
l.l_linger = 0;
l.l_onoff = 1;
// 时间
if (SOCKET_ERROR == setsockopt(g_skts[_iIdx], SOL_SOCKET, SO_LINGER, (char*)&l, sizeof(linger)))
{
sprintf(bufErr, "setsockopt(%d) SO_LINGER err : %d", _iIdx, WSAGetLastError());
zcPrintErr1(&bufErr[0]);
return;
}
// shutdown
if (SOCKET_ERROR == shutdown(g_skts[_iIdx], SD_BOTH))
{
int iErr = WSAGetLastError();
if (iErr != 10057) // 10057 socket 未connect
{
sprintf(bufErr, "shutdown(%d) SD_BOTH err : %d", _iIdx, WSAGetLastError());
zcPrintErr1(&bufErr[0]);
return;
}
}
// closesocket
if (SOCKET_ERROR == closesocket(g_skts[_iIdx]))
{
sprintf(bufErr, "closesocket(%d) err : %d", _iIdx, WSAGetLastError());
zcPrintErr1(&bufErr[0]);
return;
}
g_skts[_iIdx] = INVALID_SOCKET;
}
// *** ***
// 重新获取 socket值
g_skts[_iIdx] = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, 0);
if (g_skts[_iIdx] ==INVALID_SOCKET)
{
sprintf(bufErr, "WsaSocket(%d) INVALID_SOCKET : %d", _iIdx, WSAGetLastError());
zcPrintErr1(&bufErr[0]);
return;
}
// *** ***
// socket 事件关联
if (SOCKET_ERROR == WSAEventSelect(g_skts[_iIdx], g_hEventsConn[_iIdx], FD_CONNECT))
{
sprintf(bufErr, "WSAEventSelect(%d) SOCKET_ERROR : %d", _iIdx, WSAGetLastError());
zcPrintErr1(&bufErr[0]);
return;
}
// *** ***
// connect
sockaddr_in siConn = {0};
siConn.sin_family = AF_INET;
siConn.sin_port = htons(80);
siConn.sin_addr.S_un.S_addr = inet_addr(g_pIP[_iIdx]);
if (SOCKET_ERROR == connect(g_skts[_iIdx], (sockaddr*)&siConn, sizeof(siConn)))
{
int iErr = WSAGetLastError();
if ((iErr != 997)&&(iErr != 10035))
{
sprintf(bufErr, "connect(%d) SOCKET_ERROR : %d", _iIdx, iErr);
zcPrintErr1(&bufErr[0]);
return;
}
}
else
{
printf("connect(%d) OK", _iIdx);
}
}
void main()
{
WSADATA wsaData = {0};
int iErr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iErr != 0)
{
printf("WSAStartup failed : %d\n", WSAGetLastError());
return;
}
zcGetIP();
// event 事件线程
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
unsigned long dwErr;
__try
{
//*
// 循环 重连 TCP
int iIdx = 0;
while(1)
{
SYSTEMTIME nowTime;
GetLocalTime(&nowTime);
printf("%4d-%02d-%02d %02d:%02d:%02d.%03d --> %08X\n",
nowTime.wYear, nowTime.wMonth, nowTime.wDay,
nowTime.wHour, nowTime.wMinute, nowTime.wSecond, nowTime.wMilliseconds, g_iRand);
iIdx = 0;
while (iIdx<64)
{
zcTcpConn(iIdx);
iIdx++;
}
::Sleep(15 *1000);
}
//*/
}
__except(dwErr = GetExceptionCode())
{
// EXCEPTION_ACCESS_VIOLATION
char buf[128] =