connect方法会阻塞,请问有什么方法可以避免其长时间阻塞?

在学习嵌入式Linux网络编程中,很多同学都发现了一个问题,那就是调用connect函数时,如果服务端关闭,客户 端调用connect()函数时,发现阻塞在那里,而且利用ctrl+c信号去停止客户端程序时,需要等待一个较为长的时间才能响应了,这个时间如果大家 细心会发现,每次都是75秒的时间。那么有没有什么比较好的办法,可以以用户能接受的一个时间响应来停止掉一个正在connect连接的客户端那?

---------------------

作者:hj605635529

来源:CSDN

原文:https://blog.csdn.net/hj605635529/article/details/74157305

版权声明:本文为博主原创文章,转载请附上博文链接!




步骤1: 设置非阻塞,启动连接

实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的。这样调用

connect 可以立刻返回,根据返回值和 errno 处理三种情况:

(1) 如果返回 0,表示 connect 成功。

(2) 如果返回值小于 0, errno 为 EINPROGRESS, ?表示连接

? ? ? 建立已经启动但是尚未完成。这是期望的结果,不是真正的错误。

(3) 如果返回值小于0,errno 不是 EINPROGRESS,则连接出错了。

?

步骤2:判断可读和可写

然后把 sockfd 加入 select 的读写监听集合,通过 select 判断 sockfd

是否可写,

(1) 如果连接建立好了,,那么 sockfd 是可写的

(2) 如果连接发生错误,sockfd 也是可读和可写的。

步骤3:使用 getsockopt 函数检查错误

getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &len)

在 sockfd 都是可读和可写的情况下,我们使用 getsockopt 来检查连接

是否出错。但这里有一个可移植性的问题。

如果发生错误,getsockopt 源自 Berkeley 的实现将在变量 err 中

返回错误,getsockopt 本身返回0;(centos是这种错误)

然而 Solaris 却让 getsockopt 返回 -1,

并把错误保存在 errno 变量中。所以在判断是否有错误的时候,要处理

这两种情况。

步骤4:重新将套接字设置为阻塞

#include<stdio.h>

#include<sys/socket.h>

#include<sys/types.h>

#include<arpa/inet.h>

#include<string.h>

#include<netinet/in.h>

#include<string.h>

#include <sys/select.h>

#include<fcntl.h>

/* According to earlier standards */

#include <sys/time.h>

#include <unistd.h>

#include<errno.h>

static void usage(const char *str)

{

printf("Usage:%s,[IP],[PORT]\n",str);

}

int main(int argc ,char *argv[])

{

int sock = socket(AF_INET,SOCK_STREAM,0);

if(sock < 0)

{

perror("sock");

return 1;

}

struct sockaddr_in serv_addr;

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(atoi(argv[2]));

serv_addr.sin_addr.s_addr = inet_addr(argv[1]);

int flag,old_flag;

flag |= O_NONBLOCK;

old_flag = flag = fcntl(sock, F_SETFL, O_NONBLOCK ); //将连接套接字设置为非阻塞。

int ret = connect(sock,(struct sockaddr*)& serv_addr,sizeof(serv_addr));

if(ret != 0)

{

if(errno != EINPROGRESS) //connect返回错误。

{

printf("connect failed\n");

}

//连接正在建立

else

{

struct timeval tm;  //1.定时

tm.tv_sec = 10;

tm.tv_usec = 0;

fd_set wset;

FD_ZERO(&wset);

FD_SET(sock,&wset);

printf("selcet start\n");

int res = select(sock+1, NULL, &wset, NULL, &tm);

printf("select end\n");

if(res <= 0)

{

printf("res <= 0\n");

close(sock);

return 2;

}

if(FD_ISSET(sock,&wset))

{

printf("test \n");

int err = -1;

socklen_t len = sizeof(int);

if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len ) < 0) //两种错误处理方式

{

printf("errno :%d %s\n",errno, strerror(errno));

close(sock);

return 3;

}

if(err)

{

printf("connect faile\n");

errno = err;

close(sock);

return 4;

}

printf("connetct success\n");

}

}

}

fcntl(sock, F_SETFL, old_flag); //最后恢复sock的阻塞属性。

char buf[BUFSIZ];

while(1)

{

printf("client say# ");

fflush(stdout);

ssize_t s = read(0,buf,sizeof(buf) - 1);

if(s > 0)

{

buf[s - 1] = 0;

write(sock,buf,strlen(buf));

ssize_t s2 = read(sock,buf,sizeof(buf) -1 );

if(s2 > 0)

{

buf[s2] = 0;

printf("server echo # %s\n",buf);

}

}

}

return 0;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容