首页 > 代码库 > AcceptEx 以及 获取远程IP与port

AcceptEx 以及 获取远程IP与port

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