- 写在前面的话
- 引言
- 第 1 章 对象入门
- 第 2 章 一切都是对象
- 第 3 章 控制程序流程
- 第 4 章 初始化和清除
- 第 5 章 隐藏实施过程
- 第 6 章 类再生
- 第 7 章 多形性
- 第 8 章 对象的容纳
- 第 9 章 违例差错控制
- 第 10 章 Java IO 系统
- 第 11 章 运行期类型鉴定
- 第 12 章 传递和返回对象
- 第 十三 章 创建窗口和程序片
- 第 14 章 多线程
- 第 15 章 网络编程
- 第 16 章 设计范式
- 第 17 章 项目
- 附录 A 使用非 JAVA 代码
- 附录 B 对比 C++和 Java
- 附录 C Java 编程规则
- 附录 D 性能
- 附录 E 关于垃圾收集的一些话
- 附录 F 推荐读物
15.2 套接字
“套接字”或者“插座”(Socket)也是一种软件形式的抽象,用于表达两台机器间一个连接的“终端”。针对一个特定的连接,每台机器上都有一个“套接字”,可以想象它们之间有一条虚拟的“线缆”。线缆的每一端都插入一个“套接字”或者“插座”里。当然,机器之间的物理性硬件以及电缆连接都是完全未知的。抽象的基本宗旨是让我们尽可能不必知道那些细节。
在 Java 中,我们创建一个套接字,用它建立与其他机器的连接。从套接字得到的结果是一个 InputStream 以及 OutputStream(若使用恰当的转换器,则分别是 Reader 和 Writer),以便将连接作为一个 IO 流对象对待。有两个基于数据流的套接字类:ServerSocket,服务器用它“侦听”进入的连接;以及 Socket,客户用它初始一次连接。一旦客户(程序)申请建立一个套接字连接,ServerSocket 就会返回(通过 accept() 方法)一个对应的服务器端套接字,以便进行直接通信。从此时起,我们就得到了真正的“套接字-套接字”连接,可以用同样的方式对待连接的两端,因为它们本来就是相同的!此时可以利用 getInputStream() 以及 getOutputStream() 从每个套接字产生对应的 InputStream 和 OutputStream 对象。这些数据流必须封装到缓冲区内。可按第 10 章介绍的方法对类进行格式化,就象对待其他任何流对象那样。
对于 Java 库的命名机制,ServerSocket(服务器套接字)的使用无疑是容易产生混淆的又一个例证。大家可能认为 ServerSocket 最好叫作“ServerConnector”(服务器连接器),或者其他什么名字,只是不要在其中安插一个“Socket”。也可能以为 ServerSocket 和 Socket 都应从一些通用的基础类继承。事实上,这两种类确实包含了几个通用的方法,但还不够资格把它们赋给一个通用的基础类。相反,ServerSocket 的主要任务是在那里耐心地等候其他机器同它连接,再返回一个实际的 Socket。这正是“ServerSocket”这个命名不恰当的地方,因为它的目标不是真的成为一个 Socket,而是在其他人同它连接的时候产生一个 Socket 对象。
然而,ServerSocket 确实会在主机上创建一个物理性的“服务器”或者侦听用的套接字。这个套接字会侦听进入的连接,然后利用 accept() 方法返回一个“已建立”套接字(本地和远程端点均已定义)。容易混淆的地方是这两个套接字(侦听和已建立)都与相同的服务器套接字关联在一起。侦听套接字只能接收新的连接请求,不能接收实际的数据包。所以尽管 ServerSocket 对于编程并无太大的意义,但它确实是“物理性”的。
创建一个 ServerSocket 时,只需为其赋予一个端口编号。不必把一个 IP 地址分配它,因为它已经在自己代表的那台机器上了。但在创建一个 Socket 时,却必须同时赋予 IP 地址以及要连接的端口编号(另一方面,从 ServerSocket.accept() 返回的 Socket 已经包含了所有这些信息)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论