- 论坛徽章:
- 0
|
10可用积分
自己写了一个socket客户端,没有任何服务器端的情况下,用fcntl设置非阻塞的socket fd来connect,然后调用connect函数
然后用select函数来监视它
问题:
1. 这个select函数的参数timeval里面我设置了10秒的相应时间,但是程序运行到这里select就立即返回了。
2. 再调用getsockopt函数,optval的大小应该设为多大比较合适(我给了一个int),然后getsockopt的调用使得errno不为0,但是打印strerror确是Success。很奇怪。
源代码如下:
$ cat client.c
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<sys/select.h>
int main(void){
int s,r,ret,len,error;
char buf[20];
struct sockaddr_in sock;
fd_set rset,wset;
struct timeval tv;
tv.tv_sec=10;
s=socket(AF_INET,SOCK_STREAM,0);
if(-1==s){ printf("socket() failed\n"); return 1; }
if(0>fcntl(s,F_SETFL,fcntl(s,F_GETFL,0)|/*O_NDELAY*/O_NONBLOCK)){/*非阻塞*/
printf("fcntl failed\n");
return 1;
}
sock.sin_family=PF_INET;
sock.sin_port =htons(10080);
sock.sin_addr.s_addr=htons(INADDR_ANY);
if(-1==(ret=connect(s,(struct sockaddr*)&sock,sizeof(struct sockaddr_in)))){
if(EINPROGRESS!=errno){/*if not fcntl->O_NDELAY, fall here*/
printf("connect() failed:%s\n",strerror(errno));
return 1; }
}
if(ret==0){ printf("connection ok at once\n"); close(s); return 0; }
FD_ZERO(&rset);
FD_SET(s,&rset);
wset=rset;
if(-1==(ret=select(s+1,&rset,&wset,NULL,&tv))){ /*设置timeval时间参数*/
close(s);
printf("select error\n");
return 1;
}
if(0==ret){
close(s);
printf("timeout\n");
return 1;
}
if(/*FD_ISSET(s,&rset)*/FD_ISSET(s,&wset)){
len=sizeof(error);
errno=0;
if(0>(ret=getsockopt(s,SOL_SOCKET,SO_ERROR,(void*)&error,&len))){
close(s);
printf("getsockopt error:%s\n",strerror(errno));
return 1;
}
if(error!=0){
printf("getsockopt set error:%s\n",strerror(errno));
close(s);
return 1;
}
printf("getsockopt success\n");
}else{ close(s); printf("FD_ISSET error\n"); return 1; }
if(-1==(ret=read(s,buf,sizeof(buf)))){
printf("read() failed\n");
return 1;
}/*如果连接成功就从server读取点东西*/
printf("ret=%d\n",ret);
buf[ret-1]='\0';
printf("read:%s\n",buf);
close(s);
return 0;
}
运行结果:
$ gcc client.c && ./a.out
getsockopt set error:Success
程序立刻结束,并没有在select 那里等待。
环境: linux2.6.18+gcc4.1.2
还请 dx 指点。
[ 本帖最后由 jeanlove 于 2009-5-13 09:52 编辑 ] |
最佳答案
查看完整内容
楼主大大select的作用是检查描述符的状态,是否有数据过来,比如要查读描述符,那就检查读描述符的状态,有数据来,就会返回,否则,一直等待,知道你设定的超时时间退出。而你上面的connect的问题,不是这个。先得说下tcp/ip,每个机器只要支持tcp/ip协议,那么它一启动,就相当于有个负责tcp/ip的进程在后台运行着。再说connect,connect的过程 就是 发包收包的过程,只不过你没有看到罢了,用抓包工具可以看到。connect的过程是 ...
|