使用java.io的非阻塞服务器
每个人都知道javaio是阻塞的,javanio是非阻塞的。在IO中,您必须使用每个客户机线程模式,在NIO中,您可以为所有客户机使用一个线程 现在我的问题如下:是否可以仅使用Java IO api进行非阻塞设计。(不是NIO) 我在考虑这样一种模式(显然非常简单)使用java.io的非阻塞服务器,java,sockets,io,Java,Sockets,Io,每个人都知道javaio是阻塞的,javanio是非阻塞的。在IO中,您必须使用每个客户机线程模式,在NIO中,您可以为所有客户机使用一个线程 现在我的问题如下:是否可以仅使用Java IO api进行非阻塞设计。(不是NIO) 我在考虑这样一种模式(显然非常简单) 列表li; 用于(插座s:li){ InputStream in=s.getInputStream(); 字节[]数据=in.available(); in.读取(数据); //processData(数据);(解码数据包,编码传出
列表li;
用于(插座s:li){
InputStream in=s.getInputStream();
字节[]数据=in.available();
in.读取(数据);
//processData(数据);(解码数据包,编码传出数据包
}
还要注意,客户端将始终准备好读取数据。
您对此有何看法?这是否适用于至少可以容纳几百个没有重大性能问题的客户端的服务器?这是可能的,但毫无意义。没有select()在java.net中,您被简化为轮询套接字,这意味着在轮询之间睡觉,并且您无法知道要睡多长时间,因此您将睡得更长,因此您将浪费时间、增加延迟等;否则您必须睡很短的时间间隔,从而消耗无意义的CPU 对于仅有的几百个客户端,对于每个连接使用一个线程的传统做法没有任何异议
我不知道“客户端将始终准备好读取数据”是什么意思。你无法从服务器上分辨出这一点,如果服务器没有准备好,写入它可能会阻塞,这将彻底打乱你的applecard。你认为这将以什么方式成为非阻塞?你似乎有正确的想法,即使用可用的
模拟非阻塞I/O
方法和客户端轮询。但EJP答案是correct@JordanKaye我假设这是非阻塞的,因为我只读取准备就绪+1和available()的字节数。
在跨平台上最多看起来很奇怪。尝试此IMHO的最佳方法是使用超时轮询每个套接字(因此超时套接字opt)同样,这也不会比单线程连接解决方案更好。“客户端将始终准备好读取数据”:这意味着存在一个无限循环,用于查找可用数据,并使用工作线程进行处理(可能不太相关,只是一个注释,以便您知道服务器不会阻止写入)。谢谢你的意见,非常有用:)。@Jon“准备好阅读”和“阻止写作”完全无关。你的说法没有道理。@Jon。。。如果套接字发送缓冲区中没有空间,则服务器确实会阻止写入,这是由于对等读取速度比本地主机发送速度慢所致。
List<Socket> li;
for (Socket s : li) {
InputStream in = s.getInputStream();
byte[] data = in.available();
in.read(data);
// processData(data); (decoding packets, encoding outgoing packets
}