服务器部分代码会稍微复杂一些,由于在多用户访问服务器时要保证一定的流畅性,所以这里使用了一个任务调度的分时机制。下面请看代码:
package project.util;

import java.util.ArrayList;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;


/** *//**
*
* SocketMonitor queues the ServerFacotry objects that are timeout
* during serving the network connection and make them respectively
* restart at a proper time.</br>
* This class only can be accessed by ServerFactory class.
*
* @author Zenny Chen
*
*/

class SocketMonitor implements Runnable ...{

/** *//**
* The number of objects it can hold.
*/
private static final int MAX_THREADS = 255;

/** *//**
* The memory space where it holds the ServerFactory objects.
*/
private ArrayList<ServerFactory> list = new ArrayList<ServerFactory>(MAX_THREADS);

/** *//**
* It is a Singleton.
*/
private static SocketMonitor monitor= null;

/** *//**
*
* As a singleton, the constructor cannot be accessed.
*/
private SocketMonitor() ...{
startMonitor();
}

/** *//**
* The only method to get the object.
*
* @return the monitor
*/
synchronized static SocketMonitor getInstance() ...{
if(monitor == null)
monitor = new SocketMonitor();
return monitor;
}

/** *//**
*
* Add a ServerFactory object that is timeout during running into the
* monitor's queue.
*
* @param s reference to a ServerFactory object that will be stored.
*
*/
synchronized void addSocket(ServerFactory s) ...{
if(list.size() == MAX_THREADS)
list.remove(0);
list.add(s);
}

/** *//**
* This is the monitor's running thread method.<br>
* It is running forever unitl the server(Apache for example)
* is closed.
*/
public void run() ...{
for(;;) ...{
try ...{
Thread.sleep(1000);
}
catch(InterruptedException e) ...{
System.out.println("Sleep Interupted in monitor!");
}
ServerFactory server = digestSocket();
if(server != null)
server.beginCommunication(false);
Thread.yield();
}
}

/** *//**
* Dequeue a monitored object.
*
* @return the ServerFactory object that will be restarted.
*/
private synchronized ServerFactory digestSocket() ...{
if(list.size() != 0) ...{
return list.remove(0);
}
return null;
}

/** *//**
* Start the monitor's running thead.
*
*/
private void startMonitor() ...{
Thread thread = new Thread(this);
thread.start();
}
}




/** *//**
* This class is used to encapsulate the socket server object.</br>
* Maybe the class name is not quite proper, but now I don't wanna alter it.</br>
*
* @author Zenny Chen
*
*/

public class ServerFactory implements Runnable...{

/** *//**
* This lock is used to synchronize the threads that come from
* different clients.
*/
private static volatile Boolean lock = false;

/** *//**
* port number.</br>
* Maybe a dynamic port number is better. Hope the port is not used
* by other tasks.
*/
private static final int PORT = 8079;

/** *//**
* server socket connection time out.
*/
private static final int SOCKET_TIMEOUT = 3000;

/** *//**
* the number of retries when the connection is time out.
*/
private static final int TIMES_OF_TIMEOUT = 10;

/** *//**
* the server socket reference</br>
* It is created in this class.
*/
private ServerSocket server = null;

/** *//**
* This flag is used to delay the main process.
*/
private volatile boolean mayReturn = false;

/** *//**
* the string that is received from servlets and is to be
* output to the specified applets.
*/
private String value = "";

/** *//**
* reference to a socket monitor object.
*/
private SocketMonitor monitor = null;

/** *//**
* used to count the remaining times for retries.
*/
private int n_remainingTimeouts = TIMES_OF_TIMEOUT;

/** *//**
* Close the server socket.
*
*/
private void close() ...{
try ...{
server.close();
server = null;
lock = false;
}
catch(IOException e) ...{
System.out.println("socket server closing error!");
}
}

/** *//**
* constructor
* @param value the string that'll be output to a specified applet.
*/
public ServerFactory(String value) ...{
this.value = value;
monitor = SocketMonitor.getInstance();
}

/** *//**
* Start the server's running thread.
*
* @param ifWait the flag used to spcify whether the main process
* should be wait or not.
*/
public void beginCommunication(boolean ifWait) ...{
Thread thread = new Thread(this);
thread.start();
if(ifWait == false)
return;
while(!mayReturn);
mayReturn = false;
}

/** *//**
* Serverfactory's running method.
*/
public synchronized void run() ...{

try ...{
for(;;) ...{
while(lock) ...{
Thread.yield();
Thread.sleep(200);
}
synchronized(lock) ...{
if(lock == true)
continue;
lock = true;
break;
}
}
}
catch(InterruptedException e) ...{
System.out.println("Interrupt abnormally broken!");
}
mayReturn = true;

try ...{
System.out.println("Ready to listen!");
server = new ServerSocket(PORT);
server.setSoTimeout(SOCKET_TIMEOUT);
Socket sock = server.accept();
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
out.writeUTF(value);
System.out.println("Data transmitted!");
close();
}
catch(IOException e) ...{
if(e instanceof SocketTimeoutException) ...{
System.out.println("Time out!");
if(--n_remainingTimeouts > 0)
monitor.addSocket(this);
}
else
System.out.println("Connecting...");
close();
}

/**//*
synchronized(lock) {
try {
if(lock)
wait();
lock = true;
mayReturn = true;
System.out.println("Ready to listen!");
server = new ServerSocket(port);
Socket sock = server.accept();
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
out.writeUTF(value);
System.out.println("Data transmitted!");
//Thread.sleep(300);
server.close();
server = null;
lock = false;
notifyAll();
}
catch(IOException e) {
System.out.println("Connecting...");
}
catch(InterruptedException e) {
System.out.println("Interrupted during processing data output!");
}
}
*/
}
}
本文介绍了一种用于提高服务器在网络连接超时时的恢复能力的任务调度机制。通过使用SocketMonitor类来管理超时的ServerFactory对象,并在适当的时间重启它们,确保了多用户访问服务器时的流畅性。
729

被折叠的 条评论
为什么被折叠?



