- 浏览: 550849 次
- 性别:
- 来自: 安徽
文章分类
最新评论
-
baynjh:
jp.ne.so_net.ga2.no_ji.jcom.JCo ...
java应用jcom将word转pdf -
zgw06629:
你好,请问你都做了哪些修改呢?是在客户端还是服务端?
http上传文件深度解析-高性能http传输 -
eidolon:
翻译有误。 l ?:意思是操作符左边的符号( ...
BNF 和EBNF的含义与用法(感谢译者:Sunnybill) -
huoyj:
请教一个问题,是不是HTTP请求里面没有包含上传文件在客户端的 ...
http上传文件深度解析-高性能http传输 -
a49688448:
“认清” 我还以为google怎么你了
最近终于认清了google
可扩展的多线程通用Server框架 |
/* import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; /** * This class is a generic framework for a flexible, multi-threaded server. It * listens on any number of specified ports, and, when it receives a connection * on a port, passes input and output streams to a specified Service object * which provides the actual service. It can limit the number of concurrent * connections, and logs activity to a specified stream. */ public class Server { /** * A main() method for running the server as a standalone program. The * command-line arguments to the program should be pairs of servicenames and * port numbers. For each pair, the program will dynamically load the named * Service class, instantiate it, and tell the server to provide that * Service on the specified port. The special -control argument should be * followed by a password and port, and will start special server control * service running on the specified port, protected by the specified * password. */ public static void main ( String [] args ) { try { if ( args.length < 2 ) // Check number of arguments throw new IllegalArgumentException ( "Must specify a service" ) ; // Create a Server object that uses standard out as its log and // has a limit of ten concurrent connections at once. Server s = new Server ( System.out, 10 ) ; // Parse the argument list int i = 0 ; while ( i < args.length ) { if ( args [ i ] .equals ( "-control" )) { // Handle the -control arg i++; String password = args [ i++ ] ; int port = Integer.parseInt ( args [ i++ ]) ; // add control service s.addService ( new Control ( s, password ) , port ) ; } else { // Otherwise start a named service on the specified port. // Dynamically load and instantiate a Service class String serviceName = args [ i++ ] ; Class serviceClass = Class .forName ( serviceName ) ; Service service = ( Service ) serviceClass.newInstance () ; int port = Integer.parseInt ( args [ i++ ]) ; s.addService ( service, port ) ; } } } catch ( Exception e ) { // Display a message if anything goes wrong System.err.println ( "Server: " + e ) ; System.err.println ( "Usage: java Server " + "[-control <password> <port>] " + "[<servicename> <port> ... ]" ) ; System.exit ( 1 ) ; } } // This is the state for the server Map services; // Hashtable mapping ports to Listeners Set connections; // The set of current connections int maxConnections; // The concurrent connection limit ThreadGroup threadGroup; // The threadgroup for all our threads PrintWriter logStream; // Where we send our logging output to /** * This is the Server() constructor. It must be passed a stream to send log * output to (may be null), and the limit on the number of concurrent * connections. */ public Server ( OutputStream logStream, int maxConnections ) { setLogStream ( logStream ) ; log ( "Starting server" ) ; threadGroup = new ThreadGroup ( Server. class .getName ()) ; this .maxConnections = maxConnections; services = new HashMap () ; connections = new HashSet ( maxConnections ) ; } /** * A public method to set the current logging stream. Pass null to turn * logging off */ public synchronized void setLogStream ( OutputStream out ) { if ( out != null ) logStream = new PrintWriter ( out ) ; else logStream = null ; } /** Write the specified string to the log */ protected synchronized void log ( String s ) { if ( logStream != null ) { logStream.println ( "[" + new Date () + "] " + s ) ; logStream.flush () ; } } /** Write the specified object to the log */ protected void log ( Object o ) { log ( o.toString ()) ; } /** * This method makes the server start providing a new service. It runs the * specified Service object on the specified port. */ public synchronized void addService ( Service service, int port ) throws IOException { Integer key = new Integer ( port ) ; // the hashtable key // Check whether a service is already on that port if ( services.get ( key ) != null ) throw new IllegalArgumentException ( "Port " + port + " already in use." ) ; // Create a Listener object to listen for connections on the port Listener listener = new Listener ( threadGroup, port, service ) ; // Store it in the hashtable services.put ( key, listener ) ; // Log it log ( "Starting service " + service.getClass () .getName () + " on port " + port ) ; // Start the listener running. listener.start () ; } /** * This method makes the server stop providing a service on a port. It does * not terminate any pending connections to that service, merely causes the * server to stop accepting new connections */ public synchronized void removeService ( int port ) { Integer key = new Integer ( port ) ; // hashtable key // Look up the Listener object for the port in the hashtable final Listener listener = ( Listener ) services.get ( key ) ; if ( listener == null ) return ; // Ask the listener to stop listener.pleaseStop () ; // Remove it from the hashtable services.remove ( key ) ; // And log it. log ( "Stopping service " + listener.service.getClass () .getName () + " on port " + port ) ; } /** * This nested Thread subclass is a "listener". It listens for connections * on a specified port (using a ServerSocket) and when it gets a connection * request, it calls the servers addConnection() method to accept (or * reject) the connection. There is one Listener for each Service being * provided by the Server. */ public class Listener extends Thread { ServerSocket listen_socket; // The socket to listen for connections int port; // The port we're listening on Service service; // The service to provide on that port volatile boolean stop = false ; // Whether we've been asked to stop /** * The Listener constructor creates a thread for itself in the * threadgroup. It creates a ServerSocket to listen for connections on * the specified port. It arranges for the ServerSocket to be * interruptible, so that services can be removed from the server. */ public Listener ( ThreadGroup group, int port, Service service ) throws IOException { super ( group, "Listener:" + port ) ; listen_socket = new ServerSocket ( port ) ; // give it a non-zero timeout so accept() can be interrupted listen_socket.setSoTimeout ( 600000 ) ; this .port = port; this .service = service; } /*********************************************************************** * This is the polite way to get a Listener to stop accepting * connections **********************************************************************/ public void pleaseStop () { this .stop = true ; // Set the stop flag this .interrupt () ; // Stop blocking in accept() try { listen_socket.close () ; } // Stop listening. catch ( IOException e ) { } } /** * A Listener is a Thread, and this is its body. Wait for connection * requests, accept them, and pass the socket on to the addConnection * method of the server. */ public void run () { while ( !stop ) { // loop until we're asked to stop. try { Socket client = listen_socket.accept () ; addConnection ( client, service ) ; } catch ( InterruptedIOException e ) { } catch ( IOException e ) { log ( e ) ; } } } } /** * This is the method that Listener objects call when they accept a * connection from a client. It either creates a Connection object for the * connection and adds it to the list of current connections, or, if the * limit on connections has been reached, it closes the connection. */ protected synchronized void addConnection ( Socket s, Service service ) { // If the connection limit has been reached if ( connections.size () >= maxConnections ) { try { // Then tell the client it is being rejected. PrintWriter out = new PrintWriter ( s.getOutputStream ()) ; out.print ( "Connection refused; " + "the server is busy; please try again later.\n" ) ; out.flush () ; // And close the connection to the rejected client. s.close () ; // And log it, of course log ( "Connection refused to " + s.getInetAddress () .getHostAddress () + ":" + s.getPort () + ": max connections reached." ) ; } catch ( IOException e ) { log ( e ) ; } } else { // Otherwise, if the limit has not been reached // Create a Connection thread to handle this connection Connection c = new Connection ( s, service ) ; // Add it to the list of current connections connections.add ( c ) ; // Log this new connection log ( "Connected to " + s.getInetAddress () .getHostAddress () + ":" + s.getPort () + " on port " + s.getLocalPort () + " for service " + service.getClass () .getName ()) ; // And start the Connection thread to provide the service c.start () ; } } /** * A Connection thread calls this method just before it exits. It removes * the specified Connection from the set of connections. */ protected synchronized void endConnection ( Connection c ) { connections.remove ( c ) ; log ( "Connection to " + c.client.getInetAddress () .getHostAddress () + ":" + c.client.getPort () + " closed." ) ; } /** Change the current connection limit */ public synchronized void setMaxConnections ( int max ) { maxConnections = max; } /** * This method displays status information about the server on the specified * stream. It can be used for debugging, and is used by the Control service * later in this example. */ public synchronized void displayStatus ( PrintWriter out ) { // Display a list of all Services that are being provided Iterator keys = services.keySet () .iterator () ; while ( keys.hasNext ()) { Integer port = ( Integer ) keys.next () ; Listener listener = ( Listener ) services.get ( port ) ; out.print ( "SERVICE " + listener.service.getClass () .getName () + " ON PORT " + port + "\n" ) ; } // Display the current connection limit out.print ( "MAX CONNECTIONS: " + maxConnections + "\n" ) ; // Display a list of all current connections Iterator conns = connections.iterator () ; while ( conns.hasNext ()) { Connection c = ( Connection ) conns.next () ; out.print ( "CONNECTED TO " + c.client.getInetAddress () .getHostAddress () + ":" + c.client.getPort () + " ON PORT " + c.client.getLocalPort () + " FOR SERVICE " + c.service.getClass () .getName () + "\n" ) ; } } /** * This class is a subclass of Thread that handles an individual connection * between a client and a Service provided by this server. Because each such * connection has a thread of its own, each Service can have multiple * connections pending at once. Despite all the other threads in use, this * is the key feature that makes this a multi-threaded server * implementation. */ public class Connection extends Thread { Socket client; // The socket to talk to the client through Service service; // The service being provided to that client /** * This constructor just saves some state and calls the superclass * constructor to create a thread to handle the connection. Connection * objects are created by Listener threads. These threads are part of * the server's ThreadGroup, so all Connection threads are part of that * group, too. */ <br 发表评论
|
相关推荐
为轻量级可扩展的API服务端框架,主要用于响应http请求,开发者可通过开发自己的功能插件(.dll)进行加载以达到扩展。 丨前言 之前发过帖子《【框架】bl-api-cloud,高性能可扩展的API服务器》...
Java的产生与流行是当今Internet发展的客观要求,Java是一门各方面性能都很好的编程语言,它的基本特点是简单、面向对象、分布式、解释的、健壮的、安全的、结构中立的、可移植的、性能很优异的、多线程的、动态的,...
全书由13章组成,内容涉及到Lindx系统编程基础、TCP/UDP协议、套接字编程概念及I/O模型、高级编程中需要用到的进程问通信同步、多路复用、多线程编程和一些高级套接字控制方法、IPv6介绍以及网络安全等。...
.NET框架是建立、配置和运行Web服务以及应用程序的多语言环境,是Microsoft的新一代Web应用程序开发平台,是.NET平台最关键的部分。它包含以下两个主要部分。 (1)通用语言运行库(Common Language Runtime—CLR) ...
* Multi-threaded, event-driven core:Appweb 服务器采用多线程、事件驱动的核心架构,提供了高性能、高可靠性的 Web 服务。 * Dynamically loadable modules:Appweb 服务器支持动态加载模块,提供了高度的可扩展...
将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005 ASP.NET 2.0 中的数据源控件 使用 ASP.NET 2.0 ObjectDataSource 控件 ASP.NET 2.0 的内部变化 使用SQL Cache Dependency 代替 ...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...
07 通过form向server端发送数据 08 form表单之select标签 09 table标签 第38章 01 css的四种引入方式 02 css的四种基本选择器 03 css的组合选择器 04 css的属性选择器 05 css的伪类 06 css的选择器优先级 07 css的...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
javax.security.auth.login 此包提供可插入的验证框架。 javax.security.auth.spi 此包提供用于实现可插入验证模块的接口。 javax.security.auth.x500 此包包含应该用来在 Subject 中存储 X500 Principal 和 X500 ...
答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁,而CGI对每个请求都产生新的进程,服务完后就销毁,所以效率上...
软件框架说明多个采集线程实时读取环境中的温湿度,发送到stream消息队列;Onenet上传线程接收消息并上传到相应stream。当云端下发命令,触发Onenet_cmd_rsp_cb,在里面发送接收的控制命令到命令缓存邮箱,控制线程...
淘宝根据自己的业务特点开发了TDDL(Taobao Distributed Data Layer 外号:头都大了 ©_Ob)框架,主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的 jdbc datasource实现,...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
在多线程的环境下,Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口,如果是那样的话,Servlet只能同时处理一个请求。 Servlet依照Servlet引擎的映射来响应客户端的请求...
javax.security.auth.login 此包提供可插入的验证框架。 javax.security.auth.spi 此包提供用于实现可插入验证模块的接口。 javax.security.auth.x500 此包包含应该用来在 Subject 中存储 X500 Principal 和 X500 ...