之前《Java网络编程(三)—— Socket》介绍了客户端Socket。不过,只有客户端socket还不够,如果不能与服务器对话,客户端并没有什么用处,因此需要一个一直等待客户端连接的服务端。服务器就像坐在电话旁等电话的接线员。他们不知道谁会打电话,或者什么时间打电话,只知道当电话铃响时,就必须拿起电话与之对话,而不管对方是谁。
对于接受连接的服务器,Java提供了一个ServerSocket类表示服务器Socket。换句话说,服务器Socket的任务就是坐在电话旁等电话。从技术上讲,服务器Socket在服务器上运行,监听入站TCP连接。每个服务器Socket监听服务器机器上的一个特定端口。当远程主机上的一个客户端尝试连接这个端口时,服务器就被唤醒,协商建立客户端和服务器之间的连接,并返回一个常规的Socket对象,表示两台主机之间的Socket。换句话说,服务器Socket等待连接,而客户端Socket发起连接。一旦ServerSocket建立了连接,服务器会使用一个常规的Socket对象向客户端发送数据。数据总是通过常规socket传输。
有4个公共的ServerSocket构造函数:
这些构造函数可以指定端口、保存入站连接请求所用的队列的长度,以及要绑定的本地网络接口。
使用无参构造函数会创建一个ServerSocket对象,但并没有将它具体绑定在某一个端口,所以初始时他没有接受任何连接,但是之后可以使用bind()来进行绑定,Java提供了两个函数来进行绑定:
使用这种方式,可以允许程序在绑定端口之前设置服务器socket选项,因为有些选项在服务器socket绑定之后就会被固定住:
如果在InetSocketAddress中传入null,那么会选择任意端口。
在Java中,服务器程序的生命周期是:
- 使用一个ServerSocket()构造函数在一个特定端口创建一个新的ServerSocket。
- ServerSocket使用其accept()方法监听这个端口的入站连接。accept()会一直阻塞,直到一个客户端尝试建立连接,此时accept()将返回一个连接客户端和服务器的Socket对象。
- 根据服务器的类型,会调用Socket的getInputStream()方法、getOutputStream()方法以获得与客户端通信的输入和输出流。
- 服务器和客户端根据已协商的协议交互,直到要关闭连接。
- 服务器或客户端(或二者)关闭连接。
- 服务器返回到步骤2,等待下一次连接。
下面这个简单的例子就是一个时间服务器,这个服务器的socket在6666端口进行监听,当有客户socket连接时,服务器就会返回时间。
鉴于篇幅原因,余下关于服务器Socket的内容(请求队列长度、关闭ServerSocket、多线程服务器)可以阅读下一篇博客《Java网络编程(五)—— ServerSocket(二)》。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/11660.html