socket缓冲区已满,send会一直阻塞吗?

evfree 2013-11-04 05:02:50
RT。 比如客户端在某个时间不再收取服务端的数据,而socket又不关闭。 那么服务端的socket缓冲区势必会累积满,此时继续send的话,会阻塞不返回吗?
之前碰到一个死锁问题就是这样导致的。客户端异常了出现上述问题,导致我的服务也挂起来,本来send完后释放锁,结果锁一直得不到释放。


这是我自己封装的函数,这个函数一直没有返回。
int CEvSocket::SendAll(int iSock, const void *pMsg, int iMsgLen)
{
if ((NULL == pMsg) || (iMsgLen <= 0))
{
return EV_ERR;
}

const char *pszMsgPos = (const char *)pMsg;
int iSendCnt = iMsgLen;
while (iSendCnt > 0)
{
int iSendSz = send(iSock, pszMsgPos, iSendCnt, 0);
if (iSendSz < 0)
{
return EV_ERR;
}
pszMsgPos += iSendSz;
iSendCnt -= iSendSz;
}

return EV_OK;
}
...全文
2795 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
max_min_ 2013-11-04
  • 打赏
  • 举报
回复
会阻塞,但是不会一直在阻塞状态的!有一个超时时间的!
evfree 2013-11-04
  • 打赏
  • 举报
回复
引用 7 楼 pathletboy 的回复:
[quote=引用 2 楼 evfree 的回复:] [quote=引用 1 楼 pathletboy 的回复:] 如果是阻塞的socket的话会,非阻塞的socket则不会。
用了默认的socket是阻塞,如果用非阻塞,这种情况返回的是负数?如果不是负数,那么SendAll还是得不到返回。 头疼呀,本来想用通过心跳机制来杀掉这个阻塞起来的线程,但是强制杀又可能出现段错误,设置退出点又执行不到那片代码。真不知如何是好了。[/quote] 非阻塞的话,发出多少到系统缓冲区就返回多少,如果满的话就返回0,置错误
引用 2 楼 evfree 的回复:
[quote=引用 1 楼 pathletboy 的回复:] 如果是阻塞的socket的话会,非阻塞的socket则不会。
用了默认的socket是阻塞,如果用非阻塞,这种情况返回的是负数?如果不是负数,那么SendAll还是得不到返回。 头疼呀,本来想用通过心跳机制来杀掉这个阻塞起来的线程,但是强制杀又可能出现段错误,设置退出点又执行不到那片代码。真不知如何是好了。[/quote] #5说的
引用
-1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking.
返回-1,置errno为EWOULDBLOCK [/quote] 嗯 谢了~
pathletboy 2013-11-04
  • 打赏
  • 举报
回复
引用 2 楼 evfree 的回复:
[quote=引用 1 楼 pathletboy 的回复:] 如果是阻塞的socket的话会,非阻塞的socket则不会。
用了默认的socket是阻塞,如果用非阻塞,这种情况返回的是负数?如果不是负数,那么SendAll还是得不到返回。 头疼呀,本来想用通过心跳机制来杀掉这个阻塞起来的线程,但是强制杀又可能出现段错误,设置退出点又执行不到那片代码。真不知如何是好了。[/quote] 非阻塞的话,发出多少到系统缓冲区就返回多少,如果满的话就返回0,置错误
引用 2 楼 evfree 的回复:
[quote=引用 1 楼 pathletboy 的回复:] 如果是阻塞的socket的话会,非阻塞的socket则不会。
用了默认的socket是阻塞,如果用非阻塞,这种情况返回的是负数?如果不是负数,那么SendAll还是得不到返回。 头疼呀,本来想用通过心跳机制来杀掉这个阻塞起来的线程,但是强制杀又可能出现段错误,设置退出点又执行不到那片代码。真不知如何是好了。[/quote] #5说的
引用
-1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking.
返回-1,置errno为EWOULDBLOCK
evfree 2013-11-04
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
SOCKET OPTIONS These socket options can be set by using setsockopt(2) and read with getsockopt(2) with the socket level set to SOL_SOCKET for all sockets: SO_KEEPALIVE Enable sending of keep-alive messages on connection-oriented sockets. Expects an integer boolean flag. SO_OOBINLINE If this option is enabled, out-of-band data is directly placed into the receive data stream. Otherwise out-of-band data is only passed when the MSG_OOB flag is set during receiving. SO_RCVLOWAT and SO_SNDLOWAT Specify the minimum number of bytes in the buffer until the socket layer will pass the data to the protocol (SO_SNDLOWAT) or the user on receiving (SO_RCVLOWAT). These two values are not changeable in Linux and their argument size is always fixed to 1 byte. getsockopt is able to read them; setsockopt will always return ENOPROTOOPT. SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The parameter is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout.
谢谢,默认情况:the operation will never timeout。
赵4老师 2013-11-04
  • 打赏
  • 举报
回复
SOCKET OPTIONS These socket options can be set by using setsockopt(2) and read with getsockopt(2) with the socket level set to SOL_SOCKET for all sockets: SO_KEEPALIVE Enable sending of keep-alive messages on connection-oriented sockets. Expects an integer boolean flag. SO_OOBINLINE If this option is enabled, out-of-band data is directly placed into the receive data stream. Otherwise out-of-band data is only passed when the MSG_OOB flag is set during receiving. SO_RCVLOWAT and SO_SNDLOWAT Specify the minimum number of bytes in the buffer until the socket layer will pass the data to the protocol (SO_SNDLOWAT) or the user on receiving (SO_RCVLOWAT). These two values are not changeable in Linux and their argument size is always fixed to 1 byte. getsockopt is able to read them; setsockopt will always return ENOPROTOOPT. SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The parameter is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout.
evfree 2013-11-04
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
应该有个默认超时设置。 setsockopt SO_SNDTIMEO int Send time-out
那超时后,send返回值是什么?负数还是0?
赵4老师 2013-11-04
  • 打赏
  • 举报
回复
应该有个默认超时设置。 setsockopt SO_SNDTIMEO int Send time-out
evfree 2013-11-04
  • 打赏
  • 举报
回复
引用 1 楼 pathletboy 的回复:
如果是阻塞的socket的话会,非阻塞的socket则不会。
用了默认的socket是阻塞,如果用非阻塞,这种情况返回的是负数?如果不是负数,那么SendAll还是得不到返回。 头疼呀,本来想用通过心跳机制来杀掉这个阻塞起来的线程,但是强制杀又可能出现段错误,设置退出点又执行不到那片代码。真不知如何是好了。
pathletboy 2013-11-04
  • 打赏
  • 举报
回复
如果是阻塞的socket的话会,非阻塞的socket则不会。

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧