测试如何设置SOCKET的 Keep Alive选项

类别:软件工程 点击:0 评论:0 推荐:

//程序如下所示:

//以下宏需要自定义
#define  SIO_RCVALL  IOC_IN | IOC_VENDOR | 1
#define  SIO_RCVALL_MCAST  IOC_IN | IOC_VENDOR | 2
#define  SIO_RCVALL_IGMPMCAST  IOC_IN | IOC_VENDOR | 3
#define  SIO_KEEPALIVE_VALS  IOC_IN | IOC_VENDOR | 4
#define  SIO_ABSORB_RTRALERT  IOC_IN | IOC_VENDOR | 5
#define  SIO_UCAST_IF  IOC_IN | IOC_VENDOR | 6
#define  SIO_LIMIT_BROADCASTS  IOC_IN | IOC_VENDOR | 7
#define  SIO_INDEX_BIND  IOC_IN | IOC_VENDOR | 8
#define  SIO_INDEX_MCASTIF  IOC_IN | IOC_VENDOR | 9
#define  SIO_INDEX_ADD_MCAST  IOC_IN | IOC_VENDOR | 10
#define  SIO_INDEX_DEL_MCAST  IOC_IN | IOC_VENDOR | 11

//自定义的结构体
typedef struct tcp_keepalive
{
    u_long onoff;
    u_long keepalivetime;
    u_long keepaliveinterval;
}TCP_KEEPALIVE,*PTCP_KEEPALIVE;

int main(int argc, char* argv[])
{
    WSADATA wsaData = {0};
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
    {
        cout << "WSAStartup failed. error code = " << WSAGetLastError() << endl;
      
        cout << "Press any key exit." << endl;
        getch();
        return 0;
    }

    SOCKET s = INVALID_SOCKET;
   
    //
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)
    {
        cout << "socket failed. error code = " << WSAGetLastError() << endl;
    }
    else
    {
        int iKeepAlive = -1;
        int iOptLen = sizeof(iKeepAlive);
 //取得SO_KEEPALIVE选项信息
        if (getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&iKeepAlive, &iOptLen) == SOCKET_ERROR)
        {
            cout << "getsockopt failed. error code = " << WSAGetLastError() << endl;
        }
        else
        {
            iKeepAlive = 1;
     //这里设置成功的Keep Alive是针对操作系统的所有网络通信 
            if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&iKeepAlive, iOptLen) == SOCKET_ERROR)
            {
                cout << "setsockopt failed. error code = " << WSAGetLastError() << endl;
            }
            else
            {
                iKeepAlive = -1;
                if (getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&iKeepAlive, &iOptLen) == SOCKET_ERROR)
                {
                    cout << "getsockopt failed. error code = " << WSAGetLastError() << endl;
                }
                else if (iKeepAlive == 1)
                {
                    TCP_KEEPALIVE inKeepAlive = {0};
                    unsigned long ulInLen = sizeof(TCP_KEEPALIVE);
                    TCP_KEEPALIVE outKeepAlive = {0};
                    unsigned long ulOutLen = sizeof(TCP_KEEPALIVE);
                    unsigned long ulBytesReturn = 0;
     
      //设置socket的keep alive为10秒,并且发送次数为3次 
                    inKeepAlive.onoff = 1;
                    inKeepAlive.keepaliveinterval = 10000;
                    inKeepAlive.keepalivetime = 3;
                   
      //为选定的SOCKET设置Keep Alive,成功后SOCKET可通过Keep Alive自动检测连接是否断开 
                    if (WSAIoctl(s, SIO_KEEPALIVE_VALS,
                        (LPVOID)&inKeepAlive, ulInLen,
                        (LPVOID)&outKeepAlive, ulOutLen,
                        &ulBytesReturn, NULL, NULL) == SOCKET_ERROR)
                    {
                        cout << "WSAIoctl failed. error code = " << WSAGetLastError() << endl;
                    }
                }
            }
        }
    }

    WSACleanup();
    cout << "Press any key exit." << endl;
    getch();
    return 0;
}

本文地址:http://com.8s8s.com/it/it32935.htm