当前位置: 技术问答>linux和unix
在程序中如何判断一个socket链路在3分钟内没有收发任何信息?
来源: 互联网 发布时间:2015-12-20
本文导语: 在程序中如何判断一个socket链路在3分钟内没有收发任何信息? 在链路有读写时, 在read或write之前或之后设置一个全局标志位代表 链路忙, 然后用一个检测线程这个标志位(检测线程每隔3分钟检测一下 这个标志位) 不...
在程序中如何判断一个socket链路在3分钟内没有收发任何信息?
在链路有读写时, 在read或write之前或之后设置一个全局标志位代表
链路忙, 然后用一个检测线程这个标志位(检测线程每隔3分钟检测一下
这个标志位)
不知道这种办法是否可行? read或者write的阻塞(假设长时间读不到或
写不到数据)会不会使这种办法失效?
在链路有读写时, 在read或write之前或之后设置一个全局标志位代表
链路忙, 然后用一个检测线程这个标志位(检测线程每隔3分钟检测一下
这个标志位)
不知道这种办法是否可行? read或者write的阻塞(假设长时间读不到或
写不到数据)会不会使这种办法失效?
|
使用select. 设置超时时间
|
你的方法明显不可行,要是在第2分钟就有数据了,但恰恰在第3分钟没数据呢?
|
使用select. 设置超时时间
|
select的写集合是表明可写,而不是写的动作的发生,因此觉得用select判断socket是否发了数据是不可行的
当有数据送往socket,应用程序并不一定立即读取,所以从应用程序角度看,并不能表示收取动作的完成,但是此时整个socket层下面的数据收取是完成了的
当有数据送往socket,应用程序并不一定立即读取,所以从应用程序角度看,并不能表示收取动作的完成,但是此时整个socket层下面的数据收取是完成了的
|
像keepalive报文哈
一个简单思路,用非阻塞socket,设置timer的值,写和读之前用select判断一下可写可读性,然后再进行读写操作,读写成功后修改timer值。
调度间隙或单独线程检查timer,当超时时发送keepalive报文过去;
p.s.这种应用应该比较多,lz可以看下其他协议是怎么编的,应该有更好的模式
一个简单思路,用非阻塞socket,设置timer的值,写和读之前用select判断一下可写可读性,然后再进行读写操作,读写成功后修改timer值。
调度间隙或单独线程检查timer,当超时时发送keepalive报文过去;
p.s.这种应用应该比较多,lz可以看下其他协议是怎么编的,应该有更好的模式
|
顶jason69s().
存活包.可以判断链路正常是不是通的.
select超时判断就可以了..
存活包.可以判断链路正常是不是通的.
select超时判断就可以了..
|
不要用什么信号的,直接select搞定问题,何必要绕路解决问题呢,
学习信号的时候自然会了解信号适合的地方
学习信号的时候自然会了解信号适合的地方
|
自己写一个结构:
typedef struct my_sock
{
int sock;
int time;
}MY_SOCK;
每次sock有活动就置time=0,每次select后都检查time是不是超时不就行了?
typedef struct my_sock
{
int sock;
int time;
}MY_SOCK;
每次sock有活动就置time=0,每次select后都检查time是不是超时不就行了?
|
可以同时设到select的read_fd和write_fd集合中
套接口准备好写的三个条件:
1,套接口发送缓冲区中的可用空间字节数大于等于2048(默认值)等。
2,对方shutdown写
3,套接口出错。
>>>这样如果我这边写socket的话, select也可以立即返回??
如果满足上面的条件,你不写也返回。
套接口准备好写的三个条件:
1,套接口发送缓冲区中的可用空间字节数大于等于2048(默认值)等。
2,对方shutdown写
3,套接口出错。
>>>这样如果我这边写socket的话, select也可以立即返回??
如果满足上面的条件,你不写也返回。
|
直接用超时信号即可解决问题。
|
OK,现在你可以用pselect去代替select.其中的
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
当sigset_t* 设置成NULL的时候就和select一样的.
timeval和timespec就是时间级别不一样,一个百万,一个十亿份之一秒.
man pselect吧.
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
当sigset_t* 设置成NULL的时候就和select一样的.
timeval和timespec就是时间级别不一样,一个百万,一个十亿份之一秒.
man pselect吧.