java写服务器单线程_单线程服务器

原文作者:Jakob Jenkov 译者:李金平

下面代码展示java中一个单线程服务器的实现。单线程服务器通常不是一个服务器的最优选择,但是下面的代码能很好的说明一个服务器的生命周期。后续实现的多线程服务器代码将基于这个代码做修改。

下面是单线程服务器代码:

package servers;

import java.net.ServerSocket;

import java.net.Socket;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

public class SingleThreadedServer implements Runnable{

protected int serverPort = 8080;

protected ServerSocket serverSocket = null;

protected boolean isStopped = false;

protected Thread runningThread= null;

public SingleThreadedServer(int port){

this.serverPort = port;

}

public void run(){

synchronized(this){

this.runningThread = Thread.currentThread();

}

openServerSocket();

while(! isStopped()){

Socket clientSocket = null;

try {

clientSocket = this.serverSocket.accept();

} catch (IOException e) {

if(isStopped()) {

System.out.println("Server Stopped.") ;

return;

}

throw new RuntimeException(

"Error accepting client connection", e);

}

try {

processClientRequest(clientSocket);

} catch (IOException e) {

//log exception and go on to next request.

}

}

System.out.println("Server Stopped.");

}

private void processClientRequest(Socket clientSocket)

throws IOException {

InputStream input = clientSocket.getInputStream();

OutputStream output = clientSocket.getOutputStream();

long time = System.currentTimeMillis();

output.write(("HTTP/1.1 200 OK\n\n

" +

"Singlethreaded Server: " +

time +

"").getBytes());

output.close();

input.close();

System.out.println("Request processed: " + time);

}

private synchronized boolean isStopped() {

return this.isStopped;

}

public synchronized void stop(){

this.isStopped = true;

try {

this.serverSocket.close();

} catch (IOException e) {

throw new RuntimeException("Error closing server", e);

}

}

private void openServerSocket() {

try {

this.serverSocket = new ServerSocket(this.serverPort);

} catch (IOException e) {

throw new RuntimeException("Cannot open port 8080", e);

}

}

}

下面是调用代码:

SingleThreadedServer server = new SingleThreadedServer(9000);

new Thread(server).start();

try {

Thread.sleep(10 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Stopping Server");

server.stop();

当服务器启动后,你可以用一般的浏览器访问http://localhost:9000/

单线程服务器最核心的地方就是上面代码主循环里的黑体部分,我们再把它展示出来:

while(! isStopped()){

Socket clientSocket = null;

try {

clientSocket = this.serverSocket.accept();

} catch (IOException e) {

if(isStopped()) {

System.out.println("Server Stopped.") ;

return;

}

throw new RuntimeException("Error accepting client connection", e);

}

try {

processClientRequest(clientSocket);

} catch (IOException e) {

//log exception and go on to next request.

}

}

简短的说,服务器做了以下事情:

1 等待客户端请求

2 处理客户端请求

3 重复1,2

java服务器中的循环大多和这段循环很像,单线程服务器和多线程服务器的区别就在于单线程服务器处理客户端请求和Accept客户端连接使用的是同一个线程。而多线程服务器会把一个连接发给一个工作线程用来处理这个连接上的请求。

处理客户端连接上的请求和Accept客户端连接使用同一个线程不是一个好主意,客户端只有当服务器运行在serverSocket.accept()时,才能连接上服务器。服务器运行在serverSocket.accept()函数外的时间越长,客户端访问被拒绝的可能性就越大。这就是为什么多线程服务器将已建立连接的请求转发给工作线程的因。这样监听线程就能尽可能的运行在serverSocket.accept()之中。

d0c1501a6d8bb921cf36400dc89de69f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值