我的问题有两个:
1.java服务器端如何感知客户端断链
2.一个Server支持多个客户端连接时最优实现
说明:
针对问题一:出现的问题是,下面的代码中当客户端断链后,while(true)一直死循环导致输出一直为null
针对问题二:我现在的实现是,每来一个客户端连接,便开启一个线程去处理,感觉不是合理的处理方式,因为当成千上万个客户端去连接时,这样去创建进程根本不可能,求最优的解决方法。
希望各位码友不吝赐教,谢谢~~~
Java 服务器端代码如下,实现功能为起一个服务器端,其他客户端来连接,根据客户端发送的消息直接输出:
package MyTCP;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.NonWritableChannelException;
public class Server
{
public static void main(String[] args)
{
StartListen();
}
/**
* 设置监听的端口号
*/
public static void StartListen()
{
int port = 10001;
createTCP(port);
}
/**
*
* @param port
* @param address
*/
public static void createTCP(int port)
{
try
{
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("server list on 127.0.0.1:10001");
while (true)
{
Socket socket = serverSocket.accept();
new Thread(new ChildThred(socket)).start();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ChildThred implements Runnable
{
BufferedReader bufrea = null;
Socket socket = null;
public ChildThred(Socket socket)
{
this.socket = socket;
}
@Override
public void run()
{
try
{
bufrea = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true)
{
System.out.println("服务器端收到的客户端的消息为 : " + bufrea.readLine());
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
finally
{
try
{
bufrea.close();
socket.close();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
}
null
就应该跳出循环,把需要发送的数据发送出去,再关闭通道。这是正常的情况,异常的情况又分为两种,一种是客户端程序崩溃或异常退出,服务端在read
时会抛出connection reset by peer
异常,这时只需要捕获异常关闭通道就行了。还有一种情况是网络中断或者客户端断电,这个时候就需要心跳机制了。Tomcat(BIO模型已过时)
的处理机制。Tomcat
先用LimitLatch
做一层限流,连接到来时将Socket
封装成任务丢到线程池的任务队列,而不是立马创建线程,这样做利用了任务队列起到了缓冲作用,但是由于IO模型,这种方式还是不能充分利用服务端资源,因为线程在等待IO时阻塞了,在阻塞期间线程不能做任何其他事情,这样造成线程资源浪费。阻塞模型在高并发下自然不是最好的选择,多路复用才是最好的选择,而且相当成熟。题主可以先了解下五大IO模型,再回来看待这第二个问题。