java socket难道不能设置socket timeout吗

nijiaben 2013-04-21
今天看到PlainSocketImpl.c中的Java_java_net_PlainSocketImpl_socketSetOption这个方法里有如下代码
    /*
     * SO_TIMEOUT is a no-op on Solaris/Linux
     */
    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
        return;
    }

这是不是意味着java层面通过
socket.setSoTimeout(2000);

这样的代码不能设置SO_TIMEOUT这个值吗
nijiaben 2013-04-21
nijiaben 写道
今天看到PlainSocketImpl.c中的Java_java_net_PlainSocketImpl_socketSetOption这个方法里有如下代码
    /*
     * SO_TIMEOUT is a no-op on Solaris/Linux
     */
    if (cmd == java_net_SocketOptions_SO_TIMEOUT) {
        return;
    }

这是不是意味着java层面通过
socket.setSoTimeout(2000);

这样的代码不能设置SO_TIMEOUT这个值吗

刚看了下jdk里的代码,通过上面的方式设置的timeout只是保存在java层面的,并且只在调用connect的时候才会把这个超时时间传到jvm里面去创建连接,貌似SO_TIMEOUT是连接超时时间,并不是读数据的超时时间,unix中好像本来是没有SO_TIMEOUT这样的TCP值选项的,但是有SO_SNDTIMEO和SO_RCVTIMEO等TCP选项(但是这两个超时时间在jdk层面没有api来设置),所以比较纳闷,我一直以为SO_TIMEOUT是设置的socket读超时,是我理解有误吗
nijiaben 2013-04-21
nijiaben 写道

刚看了下jdk里的代码,通过上面的方式设置的timeout只是保存在java层面的,并且只在调用connect的时候才会把这个超时时间传到jvm里面去创建连接,貌似SO_TIMEOUT是连接超时时间,并不是读数据的超时时间,unix中好像本来是没有SO_TIMEOUT这样的TCP值选项的,但是有SO_SNDTIMEO和SO_RCVTIMEO等TCP选项(但是这两个超时时间在jdk层面没有api来设置),所以比较纳闷,我一直以为SO_TIMEOUT是设置的socket读超时,是我理解有误吗

在SocketInputStream.read中还是把这个timeout传进去了的,
public int read(byte b[], int off, int length) throws IOException {
        return read(b, off, length, impl.getTimeout());
}

不过又产生一个新的疑问,之前看《unix网络编程》中说过poll系统调用中不要把POLLERR/POLLHUP/POLLNVAL等处理异常的常量在events中进行设置(翻了下书确实是这样说的,见p144),但是我看了jvm中bsd/linux相关代码os_linux.inline.hpp都将POLLERR在events中进行了设置,如下所示
inline int os::timeout(int fd, long timeout) {
  julong prevtime,newtime;
  struct timeval t;

  gettimeofday(&t, NULL);
  prevtime = ((julong)t.tv_sec * 1000)  +  t.tv_usec / 1000;

  for(;;) {
    struct pollfd pfd;

    pfd.fd = fd;
    pfd.events = POLLIN | POLLERR;

    int res = ::poll(&pfd, 1, timeout);

    if (res == OS_ERR && errno == EINTR) {

      // On Linux any value < 0 means "forever"

      if(timeout >= 0) {
        gettimeofday(&t, NULL);
        newtime = ((julong)t.tv_sec * 1000)  +  t.tv_usec / 1000;
        timeout -= newtime - prevtime;
        if(timeout <= 0)
          return OS_OK;
        prevtime = newtime;
      }
    } else
      return res;
  }
}

难道是那本书中说的有误?
RednaxelaFX 2013-04-21
我只想说这个不是JVM相关的问题,下次请在别的区讨论此类问题…
(原本的问题留给别的经验者回答)
Global site tag (gtag.js) - Google Analytics