设为首页 加入收藏

TOP

windows socket扩展函数(二)
2017-10-13 10:22:18 】 浏览:8719
Tags:windows socket 扩展 函数
icrosoft扩展函数,它是从Mswsock.lib库中导出的,为了能够直接调用它而不链接到Mswsock.lib库(因为直接链接到这个库的话会将程序绑定在MicrosoftWinsock提供者上),需要使用WSAIoctl()将AcceptEx()加载到内存。WSAIoctl()是ioctlsocket()的扩展,它可以使用重叠I/O,函数的第3个到第6个参数是输入和输出缓冲区,在这里传递AcceptEx()函数的指针。具体如下:

// 加载扩展函数AcceptEx  
DWORD dwBytes;
GUID GuidAcceptEx = WSAID_ACCEPTEX;
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
int iResult = WSAIoctl(ListenSocket,
                        SIO_GET_EXTENSION_FUNCTION_POINTER,
                        &GuidAcceptEx,
                        sizeof(GuidAcceptEx),
                        &lpfnAcceptEx,
                        sizeof(lpfnAcceptEx),
                        &dwBytes,
                        NULL,
                        NULL);
if (iResult == SOCKET_ERROR) {
    printf("WSAIoctl failed with error: %u\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

......

//调用AcceptEx
BOOL bRetVal = lpfnAcceptEx(ListenSocket, 
                                AcceptSocket,
                                lpOutputBuf,
                                outBufLen - ((sizeof(sockaddr_in) + 16) * 2),
                                sizeof(sockaddr_in) + 16, 
                                sizeof(sockaddr_in) + 16,
                                &dwBytes, 
                                &olOverlap);
if (bRetVal == FALSE) {
    printf(L"AcceptEx failed with error: %u\n", WSAGetLastError());
    closesocket(AcceptSocket);
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}
 

2、GetAcceptExSockaddrs()

GetAcceptExSockaddrs()是专为AcceptEx()准备的,它粘贴从AcceptEx()获得的数据,将本地和远程地址传递到sockaddr结构。

void GetAcceptExSockaddrs(
_In_ PVOID lpOutputBuffer,                //指向传递给AcceptEx()接收客户第一块数据的缓冲区, 与AcceptEx()的lpOutputBuffer参数相同
_In_ DWORD dwReceiveDataLength,    //上一个参数的大小,应与AcceptEx()的dwReceiveDataLength参数一致
_In_ DWORD dwLocalAddressLength,   //为本地地址预留的空间大小,应与AcceptEx()的 dwLocalAddressLength参数一致
_In_ DWORD dwRemoteAddressLength,//为远程地址预留的空间大小,应与AcceptEx()的 dwRemoteAddressLength参数一致
_Out_ LPSOCKADDR *LocalSockaddr,   //用来获得连接的本地地址
_Out_ LPINT LocalSockaddrLength,       //用来获得连接的本地地址长度
_Out_ LPSOCKADDR *RemoteSockaddr,//用来获得连接的远程地址
_Out_ LPINT RemoteSockaddrLength     ////用来获得连接的远程地址长度
);
当使用AcceptEx时,必须使用GetAcceptExSockaddrs函数将输出缓冲区的内容解析到三个不同部分的缓冲区 (data, 
local socket address, and remote socket address)。 在windows XP 及随后版本中,当 AcceptEx函数完成操 
作并且SO_UPDATE_ACCEPT_CONTEXT选项在被接受的socket中被设置时, 与被接受socket相关的本地地址(local 
address )可以使用getsockname函数获得,类似的,与被接受socket相关的远程端地址(the remote address)可 
以使用getpeername函数获得。
使用WSAIoctl()加载GetAcceptExSockaddrs():
    DWORD dwBytes;
    GUID GuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
    LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockaddrs = NULL;
    int Result = WSAIoctl(ListenSocket,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &GuidGetAcceptExSockaddrs,
        sizeof(GuidGetAcceptExSockaddrs),
        &lpfnGetAcceptExSockaddrs,
        sizeof(lpfnGetAcceptExSockaddrs),
        &dwBytes,
        NULL,
        NULL);

3、TransmitFile

TransmitFile()函数使用操作系统的缓存管理器来发送文件数据,它避免了循环调用ReadFile() 和WSASend ()产生的多重用户模式到内核模式的切换,提高了文件传输的性能,linux的sendfile()、sendfile64()与其类似:
BOOL PASCAL TransmitFile(
   SOCKET                  hSocket, //连接套接字,不能是SOCK_DGRAM或SOCK_RAM类型
   HANDLE               
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇快速排序及STL中的sort算法 下一篇当年只会C# 所以写C++就成这样了..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目