4172|2

3

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

Help2416开发板Linux1系统学习1-socket [复制链接]

代码的流程是这样的
1 建立一个socket
2 设置socket为非阻塞
3 connect
4 把socket放到一个fd_set中
5 select 这个socket,监视可写事件
6 判断是否超时或者连接成功
   
代码如下---------------------------------------------------------------------
struct sockaddr_in servAddr;
servAddr.sin_port = htons(port);
servAddr.sin_family = AF_INET;
inet_aton(servIp,&servAddr.sin_addr);
//设置socket为非阻塞
unsigned long ul = 1;
int rm = ioctl(this->m_socket,FIONBIO,&ul);
if(rm == -1)
{
//ioctl failed
return -1;
}
if(connect(this->m_socket,(sockaddr*)&servAddr,sizeof(sockaddr)) == 0)
{
//connect success
return 0;
}

if(errno != EINPROGRESS)
{
return -1;
}
log_debug("%s",strerror(errno));
//检测socket是否可写
fd_set writeSet,readSet;
FD_ZERO(&writeSet);
FD_SET(this->m_socket,&writeSet);
int num = select(this->m_socket+1, NULL, &writeSet,NULL,tv);
if(num > 0)
{
if(FD_ISSET(this->m_socket,&writeSet))
{
  //设置socket为阻塞
  ul = 0;
  ioctl(this->m_socket,FIONBIO,&ul);
  return 0;
}
}

首先说一下这段代码的执行结果:当连接一个并不存在的socket时,select总是返回连接成功

按照这个流程,这段代码的依据就是当非阻塞时,connect立刻返回-1,同时errno设置为EINPROGRESS。然后再检测socket是否可写,如果可写了,说明socket已经建立的连接,这个时候select的会在write fd_set中把socektfd置位,同时返回,这个时候判断select的返回值和用FD_ISSET宏来判断是否socketfd是否已经被置位来判断是否连接成功。注意:所有的这一切都是建立在 “如果一个socket建立了连接,那么这个socket是可写的”,这看起来没有错,但是关键是,如果连接不成功,select是否会判断socket为可写的呢?我们知道,当连接被关闭时,select仍然判断socket是可读的。难道即使socket连接不成功,select仍然返回
可写吗?经过试验,真的是这样的。所以,上面的代码如果在异常情况下仍然正常工作,在select返回时须作如下修改:
if(FD_ISSET(this->m_socket,&writeSet))
{
int error = 0;
int errLen = sizeof(error);
if(getsockopt(this->m_socket,SOL_SOCKET,SO_ERROR,&error,(socklen_t*)&errLen) < 0)
{
  return -1;
}
if(error != 0)
{//当error等于0的时候才说明连接成功
  return -1;
}
//设置socket为阻塞
ul = 0;
ioctl(this->m_socket,FIONBIO,&ul);
return 0;
}

//以上的代码中的思想我正在用,但真的没起到连接超时的效果,一旦连接不成功还是回立即返回的.还有socket在阻塞的情况下,connect()也没有阻塞,也是立即返回的。

希望有这方面经验的朋友多多参与交流,共同提高

最新回复

为什么要把socket设置为阻塞  详情 回复 发表于 2014-8-17 12:17
点赞 关注

回复
举报

1461

帖子

1

TA的资源

纯净的硅(中级)

沙发
 
好高大上啊
 
 

回复

65

帖子

2

TA的资源

一粒金砂(中级)

板凳
 
为什么要把socket设置为阻塞
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表