usage: url_tools.exe [URL] [count] [interval(seconds)]

#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;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值