版权声明:本文为博主原创文章,未经博主允许不得转载。 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失败了。