📄 napletserversocket.java
字号:
package naplet.nsocket;
import java.io.*;
import java.net.*;
import java.math.BigInteger;
import naplet.NapletID;
/**
* NapletServerSocket is a wrapper of Java ServerSocket.It provides standard
* socket APIs and some additional functions for connection migration.
*/
public class NapletServerSocket
implements java.io.Serializable
{
/**
* ServerSocket under this NapletServerSocket
*/
private transient ServerSocket serverSocket;
/**
* use to temporarily hold the socket from Accept
*/
private transient Socket socket;
/**
* Used to temporarily hold the priority for the accepted socket.
*/
private int priority;
/**
* Used to temporarily hold the persistent flag for the accepted socket.
*/
private boolean bPersistentFlag;
/**
* Used to temporarily hold the public key for the accepted socket.
*/
private BigInteger publicKey;
/**
* The listening port this server socket used.
* This port is assigned from the new host.
*/
private int listeningPort;
/**
* status of current server socket
*/
private int socketStatus = Global.CLOSED;
/**
* socket ID of this naplet server socket.
* useful when close this server socket.
*/
private String socketID;
/**
* nid of the naplet who creates this serversocket.
*/
private NapletID nid;
/**
* if this ServerSocket is persistent
*/
private boolean bPersistent;
/**
* Construct a serversocket. The port number is allocated from a manager
* @throws IOException
*/
public NapletServerSocket( NapletID nid )
throws IOException, NoSocketControllerException
{
this( nid, false );
}
/**
* Constructs a naplet serversocket using a nid and persistent flag
* @param nid
* @param flag
* @throws IOException
*/
public NapletServerSocket( NapletID nid, boolean flag )
throws IOException, NoSocketControllerException
{
this.nid = nid;
socketID = Global.generateID();
// register nss and create a serversocket in controller
serverSocket = SocketController.registerServerSocket( this, nid,
socketID );
bPersistent = flag;
socketStatus = Global.RESUMED;
}
/**
* Not use for security reason, just keep as reference.
* Remove because of security concern.
* @param port
* @throws IOException
*/
NapletServerSocket( int port )
throws IOException
{
serverSocket = new ServerSocket( port );
listeningPort = port;
socketStatus = Global.RESUMED;
socketID = Global.generateID();
}
protected synchronized void setSocket( Socket ns )
{
setSocket( ns, false, Global.LOW_PRIORITY );
}
/**
* Set socket for the last accepted connection.
* @param ns
* @param flag
* @param pri
*/
protected synchronized void setSocket( Socket ns, boolean flag, int pri )
{
socket = ns;
this.priority = pri;
notifyAll();
bPersistentFlag = flag;
}
protected synchronized void setSocket( Socket ns,
boolean flag,
int pri, BigInteger pubKey )
{
setSocket( ns, flag, pri );
publicKey = pubKey;
}
/**
* Noticed that this function doesn't call accept of Java ServerSocket.
* It simply blocks when called and waits to be waken up by SocketController.
* Client connects to the controller, the controller hands over
* the socket and a napletsocket will be constructed based on the socket.
*
* @return
* @throws IOException
*/
public synchronized NapletSocket accept()
throws IOException, NoSocketControllerException
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception ex )
{
ex.printStackTrace();
}
}
do
{
try
{
while ( socket == null )
{
// can use a timeout to enable the SO_TIMEOUT option.
// Not very useful.
wait();
}
//construct a naplet socket using socket
NapletSocket ns = new NapletSocket( socket, bPersistentFlag );
// set some parameters
ns.setPublicKey( publicKey );
ns.setDestNapletID( nid );
ns.setPriority( this.priority );
// enbale another wait to happen
socket = null;
return ns;
}
catch ( IOException ioexception )
{
if ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception ex )
{}
}
else
{
throw ioexception;
}
} // end of catch io exc
catch ( InterruptedException inte )
{
inte.printStackTrace();
continue;
}
}
while ( true );
}
/**
* Close this naplet server socket
* @throws IOException
*/
public synchronized void close()
throws IOException
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
SocketController.removeServerSocket( socketID );
socketStatus = Global.CLOSED;
serverSocket.close();
}
public synchronized InetAddress getInetAddress()
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
return serverSocket.getInetAddress();
}
public synchronized int getLocalPort()
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
return serverSocket.getLocalPort();
}
public synchronized int getSoTimeout()
throws IOException
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
return serverSocket.getSoTimeout();
}
public synchronized void setSoTimeout( int i )
throws SocketException
{
while ( socketStatus == Global.SUSPENDED )
{
try
{
wait();
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
serverSocket.setSoTimeout( i );
}
/**
* Suspend server socket in old host. This happen before an agent migrates.
*/
public synchronized void suspend()
{
socketStatus = Global.SUSPENDED;
try
{
serverSocket.close();
}
catch ( Exception ex )
{}
serverSocket = null;
}
/**
* Resumes server socket in a new host. This happens when an agents lands on
* first lands on a new host.
* @return
*/
public synchronized boolean resume()
{
while ( true )
{
try
{
// possible that in this new host, old number wont work. SO assign a new
// one from Global
serverSocket = new ServerSocket( Global.TCPPORT++ );
listeningPort = Global.TCPPORT;
break;
}
catch ( BindException be )
{
}
catch ( Exception exception )
{
exception.printStackTrace();
return false;
}
} // end of while
socketStatus = Global.RESUMED;
try
{
notifyAll();
}
catch ( Exception exception1 )
{
exception1.printStackTrace();
}
return true;
}
/**
* Return id of the naplet which creates the ServerSocket
* @return
*/
public String getNapletID()
{
if ( nid == null )
{
return null;
}
return nid.toString();
}
/**
* Whether this server socket is persistent.
* @return
*/
public boolean isPersistent()
{
return bPersistent;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -