谁能帮忙解释一下setsockopt()?
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
这是什么意思???
问题点数:40、回复次数:17Top
1 楼huanyun(无妻徒刑)回复于 2003-11-01 20:58:35 得分 0
设置SOCKET的工作模式(比如是否广播) 等待延时Top
2 楼sdcer777(独钓雪)回复于 2003-11-01 21:01:56 得分 0
能不能具体谈谈?我写的那个代码,把sock设置以后会有什么影响?Top
3 楼xiao_potato(小土豆)回复于 2003-11-01 21:40:24 得分 2
如果过了6000ms还没发送成功,将返回。不再等待Top
4 楼cyjtan(阿碳)回复于 2003-11-01 22:32:46 得分 0
设置超时时间Top
5 楼sdcer777(独钓雪)回复于 2003-11-01 22:38:41 得分 0
那是不是::setsockopt只用于非阻塞套接字的情况??因为阻塞的是一直都在等待。Top
6 楼sdcer777(独钓雪)回复于 2003-11-01 22:57:19 得分 0
干脆我把代码写出来,请各位大侠帮我来看看为什么要如此:
............
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
continue;
}
connect(sock,(PSOCKADDR)&inAddr,sizeof(inAddr))
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = 2; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret >0 )
{
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (sock);
continue;
}
////////////////////以下是发送数据部分。
我想知道,setsockopt与select的作用各是什么?为什么在上面的代码中要这样写?(既用到了setsockopt,亦用到了select?)谢谢,在线等待!!
Top
7 楼ablefirst(able)回复于 2003-11-02 11:10:09 得分 0
setsockopt:可以灵活的设置某个套接字的行为方式或者是状态。例如设置超时时间值。
select:通过调用select函数可确定一个或多个套接字的状态,判断套接字上是否存在数据,
或者能否向一个套接字写入数据。
就这些,希望对你有帮助
Top
8 楼sdcer777(独钓雪)回复于 2003-11-02 14:06:34 得分 0
谢谢,不过我感觉还是没说清二者的关系、区别。Top
9 楼sevencat(七猫)回复于 2003-11-02 16:05:33 得分 5
setsockopt的选项很多,不光是超时处理,这点你可以去看有关的书。而且不一定是非堵塞套接字用的。不过像超时一般会设置在阻塞型套接字上的。
这段代码这样写的原因主要是因为CONNECT堵塞型套接字没有好的设置超时的办法,所以先设为非堵,然后CONNECT结束再设为阻塞型的。
select与setsockopt基本上是一点关系也没有。Top
10 楼sdcer777(独钓雪)回复于 2003-11-02 16:29:36 得分 0
可是它在connect前已经把套接字设成非堵塞的了啊》ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
................
??Top
11 楼sevencat(七猫)回复于 2003-11-02 16:38:10 得分 0
那个设置超时的可以放到CONNECT后面吧,我想。Top
12 楼sdcer777(独钓雪)回复于 2003-11-03 09:32:13 得分 0
待高人指点。。Top
13 楼sdcer777(独钓雪)回复于 2003-11-20 14:29:59 得分 0
尚未解决问题:
1、虽然setsockopt可以设置的选项有很多,但如果只设置套接字的超时选项,那是不是这个套接字必须要设置成非阻塞的呢?就如我的这个例子一样!?
2、默认情况下(即不按照本例所写的那样),connect()函数是不是阻塞的?
3、select()中也有一个时间设置,它用在经过connect()操作后的套接字上,那么,这个select()成功返回后,意味着什么?也就是说select()操作成功了,那么对这个socket有什么影响?也就是说,这个socket经过select()操作,它可以进行写操作了?这个写操作意味着什么?相对于服务器端来讲!是不是经过select()操作后,且select()成功返回了,那么说明服务器端接收数据的套接字已经准备就绪了?即服务器端的recV()函数已经成功执行了?只等客户端的套接字来写数据了?
Top
14 楼lostgdi731(O_O)回复于 2003-11-20 17:05:07 得分 0
很关注你的问题,帮你 Up 一下。Top
15 楼baojian88888(机器人)回复于 2003-11-24 09:08:40 得分 33
1、虽然setsockopt可以设置的选项有很多,但如果只设置套接字的超时选项,那是不是这个套接字必须要设置成非阻塞的呢?就如我的这个例子一样!?
不是。
你的这个例子其实是一个阻塞模式的应用
你可以看到在connect之前设置成了非阻塞的,然后判断connect成功后,又设置成了阻塞的。之所以这么做是为了解决一个问题,也就是网上讨论的很多的超时连接的问题。
2、默认情况下(即不按照本例所写的那样),connect()函数是不是阻塞的?
是阻塞的。
使用
unsigned long ul = 1;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
后,connect 函数就不会阻塞了,而是直接返回。这个时候connect是否成功并不知道,而是靠后面的select函数来判断刚才的connect是否成功了,判断的方法是看在某个时间范围内这个socket是否可写,如果可写,就表明刚才的connect成功了
ioctlsocket,setsockopt 和 select 没有什么关系,它们分别执行不同的功能
3、select()中也有一个时间设置,它用在经过connect()操作后的套接字上,那么,这个select()成功返回后,意味着什么?也就是说select()操作成功了,那么对这个socket有什么影响?也就是说,这个socket经过select()操作,它可以进行写操作了?这个写操作意味着什么?相对于服务器端来讲!是不是经过select()操作后,且select()成功返回了,那么说明服务器端接收数据的套接字已经准备就绪了?即服务器端的recV()函数已经成功执行了?只等客户端的套接字来写数据了?
select 成功了,对这个socket没有什么影响,只是表明现在socket可写了,也就表明刚才的connect成功了。
同意sevencat(七猫)的说法
“那个设置超时的可以放到CONNECT后面吧,我想。”
Top
16 楼sdcer777(独钓雪)回复于 2003-11-24 11:00:53 得分 0
如果楼上所讲,将设置超时的操作放在connect后,那么这个超时是针对什么来讲的?那不就变成了发送或接收的超时了吗?那也不是针对connect的超时了啊。Top
17 楼baojian88888(机器人)回复于 2003-11-24 12:34:16 得分 0
所说的设置超时是指这两句:
setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO, ...
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO, ...
这两句是设置发送超时和接收超时,我认为最好放在判断connect成功之后,因为只有connect成功之后才可以谈数据的发送和接收的事
当然像你写的放在connect之前也没什么问题可以运行
针对connect的超时 在那段代码里是用select判断的Top




