C++阻塞套接字特性测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/89428199

一 判断当前套接字是否为阻塞套接字

1 代码

#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

int main( int argc, char* argv[] )
{
    int sock = socket( PF_INET, SOCK_STREAM, 0 );
    assert( sock >= 0 );

    int old_option = fcntl( sock, F_GETFL );
    if(0==(old_option & O_NONBLOCK))
        printf("now socket is BLOCK mode\n"); //0 is block mode
    else
        printf("now socket is NOT BLOCK mode\n");

    return 0;
}

2 运行

[root@localhost test]# g++ test.cpp -o test
[root@localhost test]# ./test
now socket is BLOCK mode

3 说明

socket函数窗的套接字默认是阻塞套接字。判断套接字是否为阻塞可以通过系统调用fcntl先获得套接字描述符的属性标志,然后和O_NONBLOCK进行与操作,看是否为0,如果是0,则说明是阻塞套接字。

O_ACCMODE       00000003
O_RDONLY        00000000
O_WRONLY        00000001
O_RDWR          00000002
O_CREAT         00000040
O_EXCL          00000080
O_NOCTTY        00000100
O_TRUNC         00000200
O_APPEND        00000400
O_NONBLOCK      00000800
O_DSYNC         00001000
FASYNC          00002000
O_NOFOLLOW      00020000

二 统计阻塞套接字的connect超时时间

1 代码

#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

#define BUFFER_SIZE 512


int main( int argc, char* argv[] )
{
    char ip[]="192.168.0.111"; //本机的ip是192.168.0.110,192.168.0.111并不存在
    //char ip[]="192.168.0.110"
    int port = 13334;

    struct sockaddr_in server_address;
    bzero( &server_address, sizeof( server_address ) );
    server_address.sin_family = AF_INET;
    inet_pton( AF_INET, ip, &server_address.sin_addr );
    server_address.sin_port = htons( port );

    int sock = socket( PF_INET, SOCK_STREAM, 0 );
    assert( sock >= 0 );


    int old_option = fcntl( sock, F_GETFL );
    printf("noblock: %d\n", old_option & O_NONBLOCK); //0 is block mode

    struct  timeval tv1, tv2;
    gettimeofday(&tv1, NULL);

    int ret = connect( sock, ( struct sockaddr* )&server_address, sizeof( server_address ) );
    printf("connect ret code is: %d\n", ret);
    if (  ret == 0 )
    {
        printf("call getsockname ...\n");
        struct sockaddr_in local_address;
        socklen_t length;
        int ret = getpeername(sock, ( struct sockaddr* )&local_address, &length);
        assert(ret == 0);
        char local[INET_ADDRSTRLEN ];
        printf( "local with ip: %s and port: %d\n",
            inet_ntop( AF_INET, &local_address.sin_addr, local, INET_ADDRSTRLEN ), ntohs( local_address.sin_port ) );
     

        char buffer[ BUFFER_SIZE ];
        memset( buffer, 'a', BUFFER_SIZE );
        send( sock, buffer, BUFFER_SIZE, 0 );
    }
    else if (ret == -1)
    {
        gettimeofday(&tv2, NULL);
        suseconds_t msec = tv2.tv_usec - tv1.tv_usec;
        time_t sec = tv2.tv_sec - tv1.tv_sec;
        printf("time used:%d.%fs\n", sec, (double)msec / 1000000 );

        printf("connect failed...\n");
        if (errno == EINPROGRESS)
        {
            printf("unblock mode ret code...\n");
        }
    }
    else
    {
        printf("ret code is: %d\n", ret);
    }

    close( sock );
    return 0;
}

2 运行

[root@localhost test]# g++ test.cpp -o test
[root@localhost test]# ./test
noblock: 0
connect ret code is: -1
time used:3.0.005711s
connect failed...

3 说明

首先定义了和本机IP在同一子网的不真实存在的IP 192.168.0.111。定义同一个子网的假IP,要等网关回复结果后connect才知道是否能连通。从结果来看,大概等3秒后,才提示connect失败了。

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/89428199