码迷,mamicode.com
首页 > 其他好文 > 详细

AcceptEx 以及 获取远程IP与port

时间:2014-07-03 21:58:56      阅读:1300      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   数据   os   

#include <MSWSock.h>

const int     NET_BUFFER_SIZE = 1024;
char        tAcceptRecvBuf[NET_BUFFER_SIZE] = { 0 };

LPFN_ACCEPTEX    extract_AcceptEx();

LPFN_GETACCEPTEXSOCKADDRS    extract_GetAcceptExSockaddrs();

unsigned  int  post_accept()

unsigned  int __stdcall accept_callback(
    PTP_CALLBACK_INSTANCE    Instance,
    PVOID                    pvContext,
    PVOID                    pOverlapped,
    ULONG                    IoResult,
    ULONG_PTR                NumberOfBytesTransferred,
    PTP_IO                    pIo);


LPFN_ACCEPTEX    extract_AcceptEx()
{
    LPFN_ACCEPTEX    lpfnAcceptEx = NULL;
    GUID            tGuidAcceptEx = WSAID_ACCEPTEX;
    DWORD            dwBytes = 0;
    int                tResult = 0;

    tResult = WSAIoctl(
        listen_socket,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &tGuidAcceptEx, sizeof(tGuidAcceptEx),
        &lpfnAcceptEx, sizeof(lpfnAcceptEx),
        &dwBytes, NULL, NULL);

    if (SOCKET_ERROR == tResult)
    {    
        return nullptr;
    }

    return lpfnAcceptEx;
}

LPFN_GETACCEPTEXSOCKADDRS    extract_GetAcceptExSockaddrs()
{
    LPFN_GETACCEPTEXSOCKADDRS    lpfnGetAcceptExSockaddrs = NULL;
    GUID            tGuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
    DWORD            dwBytes = 0;
    int                tResult = 0;

    tResult = WSAIoctl(
        listen_socket,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &tGuidGetAcceptExSockaddrs, sizeof(tGuidGetAcceptExSockaddrs),
        &lpfnGetAcceptExSockaddrs, sizeof(lpfnGetAcceptExSockaddrs),
        &dwBytes, NULL, NULL);

    if (SOCKET_ERROR == tResult)
    {        
        return nullptr;
    }

    return lpfnGetAcceptExSockaddrs;
}

unsigned  int  post_accept()
{
    LPFN_ACCEPTEX    lpfnAcceptEx = extract_AcceptEx();
    DWORD            dwBytes = 0;
    int                tResult = 0;

    if (nullptr == lpfnAcceptEx)
    {
        return false;
    }

    BOOL            tRtn = FALSE;

    overlapex    *overlap = new overlapex();
    overlap->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == overlap->sock)
    {
        WSACleanup();
        return false;
    }

    /*
    特别要注意,当dwReceiveDataLength设置为0后,
    在使用m_lpfnGetAcceptExSockaddrs方法取得客户端地址时,
    dwReceiveDataLength也要相应的写为0,    
    否则取出的地址为0.0.0.0    
    */

    tRtn = lpfnAcceptEx(
        listen_socket, overlap->sock,
        tAcceptRecvBuf, 0,    // 表示只接收连接,不接收数据
        sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16,
        &dwBytes, (LPOVERLAPPED)overlap);

    int        tErrorCode = WSAGetLastError();

    if ((FALSE == tRtn) && (ERROR_IO_PENDING != tErrorCode))
    {
        WSACleanup();
        return false;
    }

    return true;
}

unsigned  int __stdcall accept_callback(
    PTP_CALLBACK_INSTANCE    Instance,
    PVOID                    pvContext,
    PVOID                    pOverlapped,
    ULONG                    IoResult,
    ULONG_PTR                NumberOfBytesTransferred,
    PTP_IO                    pIo)
{
    overlapex    *overlap = static_cast<overlapex*>(pOverlapped);

    if (NO_ERROR != IoResult)
    {
        if (WSAENOTSOCK != IoResult)
        {
            printf("serious error in base_recv_callback(...) !!! IoResult return:%d. query System Error Code.", IoResult);
        }

        return 0;
    }
    
    struct    sockaddr_in    *local_addr = NULL;
    struct  sockaddr_in *remote_addr = NULL;
    int local_addr_len = sizeof(sockaddr_in);
    int remote_addr_len = sizeof(sockaddr_in);

    LPFN_GETACCEPTEXSOCKADDRS    GetAcceptExSockaddrs = extract_GetAcceptExSockaddrs();
    GetAcceptExSockaddrs(
        tAcceptRecvBuf, 0,
        sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16,
        (struct sockaddr**)&local_addr, &local_addr_len,
        (struct sockaddr**)&remote_addr, &remote_addr_len);

    /*
    如果不是使用的AcceptEx这个函数,  而是使用的同步函数的话, 应该使用getpeername() & gethostname() 来获取远程机和本机的IP与PORT
    */

    printf("对方 IP & PORT: %s  %d \n", inet_ntoa(local_addr->sin_addr), ntohs(local_addr->sin_port));
    printf("本机 IP & PORT: %s  %d \n", inet_ntoa(remote_addr->sin_addr), ntohs(remote_addr->sin_port));
    
    post_recv(overlap);
    post_accept();

    return 1;
}

 

AcceptEx 以及 获取远程IP与port,布布扣,bubuko.com

AcceptEx 以及 获取远程IP与port

标签:style   blog   color   使用   数据   os   

原文地址:http://www.cnblogs.com/emyueguang/p/3820823.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!