#include <stdio.h>
#include <winsock2.h>
#ifndef WINSOCK_VERSION
#define WINSOCK_VERSION MAKEWORD(2, 2)
#endif
#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
#endif
static CRITICAL_SECTION csWriteLog;
static CRITICAL_SECTION csNetApp;
static int net_app(const char* szHostName, int iPort, const char* szData, char* szHTTPStatusCode)
{
SOCKET skt = INVALID_SOCKET;
skt = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if ( skt != INVALID_SOCKET )
{
//------------------
u_long iMode = 0; // Disabled
if ( 0 != ioctlsocket(skt, FIONBIO, &iMode) )
{
printf("error:[ioctlsocket FIONBIO][%d]\n", WSAGetLastError());
}
DWORD dwOptVal = 3000; // milliseconds
if ( 0 != setsockopt(skt, SOL_SOCKET, SO_RCVTIMEO, (const char*)&dwOptVal, sizeof(DWORD)) )
{
printf("error:[setsockopt SO_RCVTIMEO][%d]\n", WSAGetLastError());
}
if ( 0 != setsockopt(skt, SOL_SOCKET, SO_SNDTIMEO, (const char*)&dwOptVal, sizeof(DWORD)) )
{
printf("error:[setsockopt SO_SNDTIMEO][%d]\n", WSAGetLastError());
}
//------------------
EnterCriticalSection(&csNetApp);
struct hostent* psHostentTarget = gethostbyname(szHostName);
struct in_addr sInAddrTarget;
memset(&sInAddrTarget, 0, sizeof(struct in_addr));
if ( psHostentTarget != NULL )
{
sInAddrTarget = *((struct in_addr*)(psHostentTarget->h_addr));
//printf("info:[%s]\n", inet_ntoa(sInAddrTarget));//fordebug
}
else
{
printf("error:[gethostbyname][%d]\n", WSAGetLastError());
}
LeaveCriticalSection(&csNetApp);
struct sockaddr_in sTargetAddr;
memset(&sTargetAddr, 0, sizeof(struct sockaddr_in));
sTargetAddr.sin_family = AF_INET;
sTargetAddr.sin_addr.s_addr = inet_addr(inet_ntoa(sInAddrTarget));
sTargetAddr.sin_port = htons(iPort);
if ( 0 == connect(skt, (const struct sockaddr*)&sTargetAddr, sizeof(struct sockaddr_in)) )
{
const char* bufDataSend = szData;
int iBytesTotal = strlen(bufDataSend);
int iBytesSent = 0;
while ( iBytesTotal > 0 )
{
iBytesSent = send(skt, bufDataSend, iBytesTotal, 0);
if ( SOCKET_ERROR == iBytesSent )
{
printf("error:[send][%d]\n", WSAGetLastError());
}
else
{
bufDataSend += iBytesSent;
iBytesTotal -= iBytesSent;
}
}
char bufDataRecv[32];
int iBytesRecvd = 0;
memset(bufDataRecv, 0, sizeof(bufDataRecv));
iBytesRecvd = recv(skt, bufDataRecv, sizeof(bufDataRecv)-1, 0);
/*
while ( iBytesRecvd > 0 ) // recv all
{
printf("recv:[%d] [%s]\n", iBytesRecvd,bufDataRecv);//fordebug
memset(bufDataRecv, 0, sizeof(bufDataRecv));
iBytesRecvd = recv(skt, bufDataRecv, sizeof(bufDataRecv)-1, 0);
}
*/
if ( iBytesRecvd > 0 )
{
if ( sizeof(bufDataRecv)-1 == iBytesRecvd )
{
char* pcCRLF = strstr(bufDataRecv, "\r\n");
if ( pcCRLF != NULL )
{
memcpy(szHTTPStatusCode, bufDataRecv, pcCRLF-bufDataRecv);
szHTTPStatusCode[pcCRLF-bufDataRecv] = '\0';
}
}
}
if ( 0 == iBytesRecvd )
{
printf("info:[recv][the connection has been gracefully closed]\n");
}
else if ( SOCKET_ERROR == iBytesRecvd )
{
if ( WSAETIMEDOUT == WSAGetLastError() )
{
printf("info:[recv][WSAETIMEDOUT]\n");
}
else
{
printf("error:[recv][%d]\n", WSAGetLastError());
}
}
if ( 0 != shutdown(skt, SD_BOTH) )
{
printf("error:[shutdown SD_BOTH][%d]\n", WSAGetLastError());
}
}
else
{
printf("error:[connect][%d]\n", WSAGetLastError());
//10060 WSAETIMEDOUT
}
//------------------
if ( 0 != closesocket(skt) )
{
printf("error:[closesocket][%d]\n", WSAGetLastError());
}
return 0;
}
return -1;
}
static int SendHttpRequest(const char* szHostName, const char* szRequestFile, int iPort, char* szHTTPStatusCode)
{
const char* szRequestMethod = "GET";
//const char* szRequestMethod = "HEAD";
char szHTTPRequestHeader[256];
if ( 80 == iPort )
{
sprintf(szHTTPRequestHeader, "%s %s HTTP/1.1\r\nHost:%s\r\n\r\n", szRequestMethod,szRequestFile,szHostName);
}
else
{
sprintf(szHTTPRequestHeader, "%s %s HTTP/1.1\r\nHost:%s:%d\r\n\r\n", szRequestMethod,szRequestFile,szHostName,iPort);
}
//printf("info:[%s]\n", szHTTPRequestHeader);//fordebug
return net_app(szHostName, iPort, szHTTPRequestHeader, szHTTPStatusCode);
}
//todo
static int ParseURL(const char* szURL, char* szHostName, char* szRequestFile, int& iPort)
{
char* pcPos1 = strstr(szURL, "://");
if ( pcPos1 != NULL )
{
char* pcPos2 = strstr(pcPos1+3, "/");
if ( pcPos2 != NULL )
{
if ( (pcPos2 - szURL +1) == (int)strlen(szURL) )
{
//example: http://news.sohu.com/
memcpy(szHostName, pcPos1+3, pcPos2-pcPos1+1-4);
szHostName[pcPos2-pcPos1+1-4] = '\0';
strcpy(szRequestFile, "/");
iPort = 80;
return 0;
}
else
{
//example: http://news.sohu.com/20150106/n407559320.shtml
memcpy(szHostName, pcPos1+3, pcPos2-pcPos1+1-4);
szHostName[pcPos2-pcPos1+1-4] = '\0';
memcpy(szRequestFile, pcPos2, strlen(szURL)-(pcPos2-szURL));
szRequestFile[strlen(szURL)-(pcPos2-szURL)] = '\0';
iPort = 80;
return 0;
}
}
}
return -1;
}
static void WriteLog(const char* szURL, const char* szLog, const char* szHTTPStatusCode)
{
EnterCriticalSection(&csWriteLog);
char szCode[8];
memset(szCode, 0, sizeof(szCode));
char* pcPos1 = strstr(szHTTPStatusCode, " ");
if ( pcPos1 != NULL )
{
char* pcPos2 = strstr(pcPos1+1, " ");
if ( pcPos2 != NULL )
{
memcpy(szCode, pcPos1+1, pcPos2-pcPos1+1-2);
szCode[pcPos2-pcPos1+1-2] = '\0';
}
}
SYSTEMTIME sTime;
GetLocalTime(&sTime);
char szData[256];
sprintf(szData, "%02d%02d%02d-%s-%s\r\n", sTime.wHour,sTime.wMinute,sTime.wSecond,szURL,szCode);
//printf("info:[%s]\n", szData);//fordebug
char szFileName[32];
sprintf(szFileName, "%04d%02d%02d.txt", sTime.wYear,sTime.wMonth,sTime.wDay);
FILE* fp = fopen(szFileName, "awb");
if (fp)
{
if ( strlen(szData) != fwrite(szData, 1, strlen(szData), fp) )
{
printf("error:[fwrite]\n");
}
fclose(fp);
}
LeaveCriticalSection(&csWriteLog);
}
struct ThreadParam
{
const char* szURL;
const char* szLog;
};
static DWORD WINAPI threadFunc(LPVOID lpThreadParameter)
{
struct ThreadParam* psThreadParam = (struct ThreadParam*)lpThreadParameter;
const char* szURL = psThreadParam->szURL;
const char* szLog = psThreadParam->szLog;
char szHostName[64];
char szRequestFile[128];
int iPort;
if ( 0 == ParseURL(szURL, szHostName, szRequestFile, iPort) )
{
int ret = 0;
char szHTTPStatusCode[128];
memset(szHTTPStatusCode, 0, sizeof(szHTTPStatusCode));
ret = SendHttpRequest(szHostName, szRequestFile, iPort, szHTTPStatusCode);
WriteLog(szURL, szLog, szHTTPStatusCode);
return ret;
}
else
{
printf("error:[ParseURL]\n");
}
return -1;
}
static int socket_app(const char* szURL, int iThreadNum, const char* szLog)
{
WSADATA wsadata;
memset(&wsadata, 0, sizeof(WSADATA));
if ( 0 == WSAStartup(WINSOCK_VERSION, &wsadata) )
{
InitializeCriticalSection(&csWriteLog);
InitializeCriticalSection(&csNetApp);
HANDLE* rghThread = new HANDLE[iThreadNum];
int iThreadIndex = 0;
struct ThreadParam sThreadParam;
sThreadParam.szURL = szURL;
sThreadParam.szLog = szLog;
for ( int i = 0; i < iThreadNum; ++i )
{
HANDLE hThreadTemp = CreateThread(NULL, 16*1024, threadFunc, (PVOID)&sThreadParam, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
if ( hThreadTemp != NULL )
{
rghThread[iThreadIndex] = hThreadTemp;
iThreadIndex++;
}
else
{
printf("error:[CreateThread][%d]\n", (int)GetLastError());
//8 ERROR_NOT_ENOUGH_MEMORY
}
}
/*if ( WAIT_FAILED == WaitForMultipleObjects(iThreadIndex, rghThread, TRUE, INFINITE) )
{
printf("error:[WaitForMultipleObjects][%d]\n", (int)GetLastError());
//87 ERROR_INVALID_PARAMETER MAXIMUM_WAIT_OBJECTS=64
}*/
for ( int i = 0; i < iThreadIndex; ++i )
//for ( int i = iThreadIndex-1; i >= 0; --i )
{
if ( WAIT_FAILED == WaitForSingleObject(rghThread[i], INFINITE) )
{
printf("error:[WaitForSingleObject][%d]\n", (int)GetLastError());
}
if ( TRUE != CloseHandle(rghThread[i]) )
{
printf("error:[CloseHandle][%d]\n", (int)GetLastError());
}
}
delete[] rghThread;
DeleteCriticalSection(&csWriteLog);
DeleteCriticalSection(&csNetApp);
if ( 0 != WSACleanup() )
{
printf("error:[WSACleanup][%d]\n", WSAGetLastError());
}
return 0;
}
else
{
printf("error:[WSAStartup][%d]\n", WSAGetLastError());
}
return -1;
}
static void usage()
{
printf("------------------------------------------------------\r\n");
printf("-------------- v0.3 2015-01-06 15:35:39 --------------\r\n");
printf("usage: url_tools.exe [URL] [count] [interval(seconds)]\r\n");
printf("------------------------------------------------------\r\n");
}
int main(int argc, char* argv[])
{
if ( argc != 4 )
{
usage();
return -1;
}
else
{
while (true)
{
socket_app(argv[1], atoi(argv[2]), "");
printf(".");
Sleep(atoi(argv[3])*1000);
}
return 0;
}
}
usage: url_tools.exe [URL] [count] [interval(seconds)]
最新推荐文章于 2022-05-13 10:05:35 发布