二、多线程服务器程序举例
以下是我们在项目中采用的多线程服务器程序的架构,可以在此基础上对命令进行扩充。本例未涉及数据库。如 果在线程运行中需要根据用户指令对数据库进行更新操作,则应注意线程间的同步问题,使同一更新方法一次只能由一个线程调用。这里我们有两个类, receiveServer包含启动代码(main ()),并初始化ServerSocket的实例,在accept方法返回用户请求后,将返回的套接字(Socket)交给生成的线程类 serverThread的实例,直到该用户结束连接。
启动该服务器程序后,可用telnet machine port命令连接,其中machine为本机名或地址,port为程序中指定的端口。也可以编写特定的客户机软件通过TCP的Socket套接字建立连接。
以下是我们在项目中采用的多线程服务器程序的架构,可以在此基础上对命令进行扩充。本例未涉及数据库。如 果在线程运行中需要根据用户指令对数据库进行更新操作,则应注意线程间的同步问题,使同一更新方法一次只能由一个线程调用。这里我们有两个类, receiveServer包含启动代码(main ()),并初始化ServerSocket的实例,在accept方法返回用户请求后,将返回的套接字(Socket)交给生成的线程类 serverThread的实例,直到该用户结束连接。
//类receiveServer import java.io.*; import java.util.*; import java.net.*; public class receiveServer{ final int RECEIVE_PORT=9090; //该服务器的端口号 //receiveServer的构造器public receiveServer() {ServerSocket rServer=null; //ServerSocket的实例 Socket request=null; //用户请求的套接字Thread receiveThread=null; try{ rServer=new ServerSocket(RECEIVE_PORT); //初始化ServerSocket System.out.println("Welcome to the server!"); System.out.println(new Date()); System.out.println("The server is ready!"); System.out.println("Port: "+RECEIVE_PORT); while(true){ //等待用户请求 request=rServer.accept(); //接收客户机连接请求receiveThread=new serverThread(request); //生成serverThread的实例 receiveThread.start(); //启动serverThread线程 } } catch(IOException e){ System.out.println(e.getMessage()) ; } } public static void main(String args[]){ new receiveServer(); } //end of main} //end of class//类serverThreadimport java.io.*; import java.net.*; class serverThread extends Thread {Socket clientRequest; //用户连接的通信套接字BufferedReader input; //输入流PrintWriter output; //输出流 public serverThread(Socket s) { //serverThread的构造器 this.clientRequest=s; //接收receiveServer传来的套接字 InputStreamReader reader; OutputStreamWriter writer; try{ //初始化输入、输出流 reader=new InputStreamReader(clientRequest.getInputStream()); writer=new OutputStreamWriter(clientRequest.getOutputStream()); input=new BufferedReader(reader); output=new PrintWriter(writer,true); } catch(IOException e){ System.out.println(e.getMessage());} output.println("Welcome to the server!"); //客户机连接欢迎词 output.println("Now is: "+new java.util.Date()+" "+ "Port:"+clientRequest.getLocalPort()); output.println("What can I do for you?"); } public void run(){ //线程的执行方法 String command=null; //用户指令 String str=null; boolean done=false; while(!done){ try{ str=input.readLine(); //接收客户机指令 }catch(IOException e){ System.out.println(e.getMessage()); } command=str.trim().toUpperCase(); if(str==null || command.equals("QUIT")) //命令quit结束本次连接 done=true; else if(command.equals("HELP")){ //命令help查询本服务器可接受的命令 output.println("query"); output.println("quit"); output.println("help"); } else if(command.startsWith("QUERY")){ //命令 query output.println("OK to query something!"); }//else if …….. //在此可加入服务器的其他指令 else if(!command.startsWith("HELP") && !command.startsWith("QUIT") && !command.startsWith("QUERY")){output.println("Command not Found! Please refer to the HELP!"); } } //end of while try { clientRequest.close(); //关闭套接字 } catch(IOException e){ System.out.println(e.getMessage()); } command=null; } //end of run |
启动该服务器程序后,可用telnet machine port命令连接,其中machine为本机名或地址,port为程序中指定的端口。也可以编写特定的客户机软件通过TCP的Socket套接字建立连接。