46 ServerSocket 源码及面试题

引导语

上一小节我们学习了 Socket,本文我们来看看服务端套接字 API:ServerSocket,本文学习完毕之后,我们就可以把客服端 Socket 和服务端 ServerSocket 串联起来,做一个真实的网络通信的 demo 了。

1 类属性

ServerSocket 的主要作用,是作为服务端的套接字,接受客户端套接字传递过来的信息,并把响应回传给客户端,其属性非常简单,如下:

private boolean created = false;// 已创建
private boolean bound = false;// 绑定
private boolean closed = false;// 已关闭
// 底层的功能都依靠 SocketImpl 来实现
private SocketImpl impl;

ServerSocket 和 Socket 一样,底层都是依靠 SocketImpl 的能力,而 SocketImpl 底层能力的实现基本上都是 native 方法实现的。

2 初始化

初始化大概可以分成两类:无参构造器和有参构造器。

  1. 无参构造器做的事情比较简单,只指定了 SocketImpl 为 SocksSocketImpl 类;
  2. 有参构造器有几种初始化的形式,我们一起来看一下参数最多的构造器的源码。
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {// 默认是 SocksSocketImpl 实现setImpl();// 端口必须大于 0,小于 65535if (port < 0 || port > 0xFFFF)throw new IllegalArgumentException("Port value out of range: " + port);// 最大可连接数如果小于1,那么采取默认的 50if (backlog < 1)backlog = 50;try {// 底层 navtive 方法bind(new InetSocketAddress(bindAddr, port), backlog);} catch(SecurityException e) {close();throw e;} catch(IOException e) {close();throw e;}
}

入参 port 指的是 ServerSocket 需要绑定本地那个端口。

入参 backlog 指的是服务端接受客户端连接队列的最大长度,这里需要注意的是,这里并不是限制客户端连接的个数,我们在 JDK8 版本下做过实验,我们把服务端的 backlog 设置成 1,并且变慢服务端的处理速度,当服务端并发请求过来时,并不是第二个请求过来就拒绝连接,我们在实际工作中,最好也不要用 backlog 来限制客户端连接的个数。

还有点需要注意的是 backlog 小于 1 时,backlog 会被设置成默认的 50。

入参 InetAddress 表示 ip 地址。

3 bind

bind 方法主要作用是把 ServerSocket 绑定到本地的端口上,只有当我们使用无参构造器初始化 ServerSocket 时,才会用到这个方法,如果使用有参构造器的话,在初始化时就已经绑定到本地的端口上了。

配合无参构造器,一般我们这么用:

// 进行初始化
ServerSocket serverSocket = new ServerSocket();
// 进行绑定
serverSocket.bind(new InetSocketAddress("localhost", 7007));

4 accept

accept 方法主要是用来 ServerSocket 接受来自客户端的套接字的,如果此时没有来自客户端的请求时,该方法就会一直阻塞,如果有通过 setSoTimeout 方法设置超时时间,那么 accept 只会在超时间内阻塞,过了超时时间就会抛出异常。

bind 和 accept 方法底层都是 native 方法实现,我们就不看源码了。

5 面试题

5.1 说说你对 Socket 和 ServerSocket 的理解?

答:两者我们都可以称为套接字,底层基于 TCP/UDP 协议,套接字对底层协议进行了封装,让我们使用时更加方便,Socket 常被使用在客户端,用于向服务端请求数据和接受响应,ServerSocket 常用于在服务端,用于接受客户端的请求并进行处理,两者其底层使用都是依靠 SocketImpl 的子类的 native 方法。

5.2 说说对 SocketOptions 中的 SO_TIMEOUT 的理解?

答:SocketOptions 类有很多属性设置,比如 SO_TIMEOUT 、SO_LINGER 等等,这些问题说一下自己的理解即可,可以参考 《Socket 源码及面试题》 中对各种属性的解析。

5.3 在构造 Socket 的时候,我可以选择 TCP 或 UDP 么?应该如何选择?

答:可以的,Socket 有三个参数的构造器,第三个参数表示你想使用 TCP 还是 UDP。

5.4 TCP 有自动检测服务端是否存活的机制么?有没有更好的办法?

答:有的,我们可以通过 setKeepAlive 方法来激活该功能,如果两小时内,客户端和服务端的套接字之间没有任何通信,TCP 会自动发送 keepalive 探测给服务端,预测服务端有三种情况:

  1. 服务端使用预期的 ACK 回复,说明一切正常;
  2. 服务端回复 RST,表示服务端处于死机或者重启状态,终止连接;
  3. 没有得到服务端的响应(会尝试多次),表示套接字已经关闭了。

但我们并不建议使用这种方式,我们可以自己起一个定时任务,定时的访问服务端的特殊接口,如果服务端返回的数据和预期一致,说明服务端是存活的。

总结

Socket 和 ServerSocket 在源码方面没啥特别可说的地方,基本都是一些设置,底层实现都是 native 的方法,但面试官会从此延伸到一些网络协议方面的知识,因为这已经超出本专栏的范畴了,感兴趣的同学可以自行百度。

面试官系统精讲Java源码及大厂真题 - 46 ServerSocket 源码及面试题相关推荐

  1. 面试官系统精讲Java源码及大厂真题 - 34 只求问倒:连环相扣系列锁面试题

    34 只求问倒:连环相扣系列锁面试题 自信和希望是青年的特权. 引导语 面试中,问锁主要是两方面:锁的日常使用场景 + 锁原理,锁的日常使用场景主要考察对锁 API 的使用熟练度,看看你是否真的使用过 ...

  2. 面试官系统精讲Java源码及大厂真题 - 48 一起看过的 Java 源码和面试真题

    48 一起看过的 Java 源码和面试真题 不为了源码而读源码,只为了更好的实践 持续几个月,我们的专栏终于结束了,这篇总结篇,我们又想回到当初写这篇专栏的初心:我们不为读源码而读源码,只是为了更好的 ...

  3. 面试官系统精讲Java源码及大厂真题 - 36 从容不迫:重写锁的设计结构和细节

    36 从容不迫:重写锁的设计结构和细节 受苦的人,没有悲观的权利. --尼采 引导语 有的面试官喜欢让同学在说完锁的原理之后,让你重写一个新的锁,要求现场在白板上写出大概的思路和代码逻辑,这种面试题目 ...

  4. 面试官系统精讲Java源码及大厂真题 - 38 线程池源码面试题

    38 线程池源码面试题 与有肝胆人共事,从无字句处读书. --周恩来 引导语 线程池在日常面试中占比很大,主要是因为线程池内容涉及的知识点较广,比如涉及到队列.线程.锁等等,所以很多面试官喜欢把线程池 ...

  5. 面试官系统精讲Java源码及大厂真题 - 24 举一反三:队列在 Java 其它源码中的应用

    24 举一反三:队列在 Java 其它源码中的应用 世上无难事,只要肯登攀. 引导语 队列除了提供 API 供开发者使用外,自身也和 Java 中其他 API 紧密结合,比如线程池和锁,线程池直接使用 ...

  6. 面试官系统精讲Java源码及大厂真题 - 17 并发 List、Map源码面试题

    17 并发 List.Map源码面试题 梦想只要能持久,就能成为现实.我们不就是生活在梦想中的吗? 引导语 并发 List 和 Map 是技术面时常问的问题,问的问题也都比较深入,有很多问题都是面试官 ...

  7. 面试官系统精讲Java源码及大厂真题 - 11 HashSet、TreeSet 源码解析

    11 HashSet.TreeSet 源码解析 更新时间:2019-09-16 19:37:35 成功的奥秘在于目标的坚定. --迪斯雷利 引导语 HashSet.TreeSet 两个类是在 Map ...

  8. 面试官系统精讲Java源码及大厂真题 - 10 Map源码会问哪些面试题

    10 Map源码会问哪些面试题 更新时间:2019-09-10 10:34:08 人的一生可能燃烧也可能腐朽,我不能腐朽,我愿意燃烧起来! --奥斯特洛夫斯基 引导语 Map 在面试中,占据了很大一部 ...

  9. 面试官系统精讲Java源码及大厂真题 - 07 List 源码会问哪些面试题

    07 List 源码会问哪些面试题 勤学如春起之苗,不见其增,日有所长. --陶潜 引导语 List 作为工作中最常见的集合类型,在面试过程中,也是经常会被问到各种各样的面试题,一般来说,只要你看过源 ...

最新文章

  1. 俄罗斯网络安全治理及其启示
  2. 把cygwin加入右键菜单
  3. tzwhere模块 根据经纬度判断时区
  4. Python3文件操作详解 Python3文件操作大全
  5. SAP FSM 学习笔记(四) : 现场服务技师使用的移动应用
  6. 事务未提交 别人能读取到吗_Mysql 事务-面试笔记
  7. thinkphp第一节结构
  8. Linux内核入门之路 (非广告)
  9. 【Python】pyCryptodome模块实现AES加密、解密
  10. matlab中Cci,【指标量化】超买超卖——CCI 顺势指标
  11. 三十六進制之間隨便轉換
  12. 关于×××隧道技术在使用中的优势
  13. 装机量 2 亿,这款国产物联网操作系统为何是“小而美”?
  14. linux-推荐两款好用的录屏软件
  15. 20 道 Redis 面试题,面试官能问的都被我找到了
  16. 山科大离散数学期末考试_西安电子科技大学网络与继续教育学院 2020 学年上学期 《离散数学》期末考试试题...
  17. html验证码自动刷新,验证码输入错误后自动刷新验证码
  18. wps ppt, 版式与母版
  19. 封装jquery的方法
  20. 计算机mac地址怎么修改密码,如何修改苹果电脑mac地址?

热门文章

  1. 如何优化网页转化率?(下篇)
  2. JavaScript 需要清楚的10件事
  3. 如何使用HTML5嵌入视频
  4. UITableView 系列五 :自定义UITableViewCell (实例)
  5. jQuery插件Label Effect制作个性化的文字特效
  6. Linux——Vi/Vim如何消除搜索后的关键字高亮
  7. Linux sed命令高级用法精讲
  8. 【AI视野·今日Robot 机器人论文速览 第二十五期】Fri, 1 Oct 2021
  9. 第四天的作业与答案,py直播
  10. 10-mysql-分组查询