在linux下玩转带有超时时间的connect函数------某次面试遇到过

972 篇文章 329 订阅
461 篇文章 67 订阅

        在之前的博文中, 我们在Windows下玩过带有超时时间的, 本文我们在linux下来玩。 在某次面试中, 还被遇到了这个问题, 有意思。

        直接上客户端代码:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <time.h>

int main(int argc, char *argv[]) // 注意输入参数, 带上ip和port
{
    int sockClient = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in addrSrv;
    addrSrv.sin_addr.s_addr = inet_addr(argv[1]);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(atoi(argv[2]));

	fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK);  
	
    int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
	printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno)); // 返回-1不一定是异常

	if (iRet != 0)  
	{  
	   	if(errno != EINPROGRESS)
		{
			printf("connect error:%s\n", strerror(errno));  
		}
	   	else  
		{
			struct timeval tm = {5, 0};	
			fd_set wset, rset;  
			FD_ZERO(&wset);	
			FD_ZERO(&rset);	
			FD_SET(sockClient, &wset);  
			FD_SET(sockClient, &rset); 
			int time1 = time(NULL);
			int n = select(sockClient + 1, &rset, &wset, NULL, &tm);  
			int time2 = time(NULL);
			printf("time gap is %d\n", time2 - time1);

			if(n < 0)	
			{  
			   printf("select error, n is %d\n", n);  
			}  
			else if(n == 0)  
			{  
			   printf("connect time out\n");  
			}  
			else if (n == 1)  
			{
			   if(FD_ISSET(sockClient, &wset))	
			   {  
				   printf("connect ok!\n");  
				   fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK);  
			   }  
			   else  
			   {  
				   printf("unknow error:%s\n", strerror(errno));	
			   }  
			}
			else
			{
				printf("oh, not care now, n is %d\n", n);
			}
		}  
	}  

	printf("I am here!\n");
    getchar();
    close(sockClient);
    return 0;
}
        服务端代码, 我们已经写过多次, 本文就不写了。

        经测试, 上述程序OK,  用tcpdump抓包, 还能学到不少东西, 比如SYN包重传, RST包等。 有点意思。



        

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值