发布网友 发布时间:2022-04-22 06:22
共1个回答
热心网友 时间:2023-05-28 14:40
看 Oracle 官方教程,同步式的 Socket 就是传统的一问一答方式,它就是你需要的。
客户端先 socket.getOutputStream().write(...); 之后到 socket.getInputStream().read(byte[]) 在循环中读取直到 read 方法返回 -1 或你期望的字节数已经全部收到了就停下来,如果不尝试停下来,后面的 read 将会阻塞等待。
http://docs.oracle.com/javase/tutorial/networking/sockets/index.html
基于性能改进,一般我们需要使用 NIO 异步的 socket,只需要一个线程负责通信,每个线程都有自己的出站消息队列和入站消息队列,以线程为 key 区分开,通信线程只负责把各自的消息从出站队列中发送去并把收到的消息放入入站队列中,应用程序线程就去各自的消息队列中取消息就可以了。因为每个应用线程有各自的消息队列,我们把消息放入出站队列之后就到入站队列上用同步锁等待的方法阻塞到有消息回答时为止。
关于 NIO non-blocking 非阻塞式 socket,下面有一个 NBTimeServer 例子,它讲的是服务端。客户端与此类似,
http://docs.oracle.com/javase/7/docs/technotes/guides/io/example/index.html
NIO 通信线程样例。
public void run()
追问非常感谢如此耐心并全面的回答.
还有一问在同步式的 Socket中用OutputStream 发送完报文后.是否需要关闭当前socket.
然后新开socket,调用 socket.getInputStream().read()方法来进行等待.
如果不关闭是否会造成阻塞?
追答发送完了不用关吧,读取完了再关才合适啊。你可以测试嘛。比如连接到一个像 oracle 这样的第三方服务器程序(不是你写的,免得服务器端有没有bug你还得确认)来测试你的客户端程序。
按理说 output stream 不应该影响 input stream 是否阻塞,因为现有的 Socket 基本上工作在全双式模式,也就是说收和发两个方向是互不干涉的,但如果我们尝试关闭就难说了,当然如果对方正在 read 时阻塞了而且它也我们一样地使用一问一答的方式当然可能会出现死锁的情况,因为我们不知道 Java 底层的功能是如何处理建立连接时的状态通知的,因此我们在所有事情处理完了再闭吧。