This is a TCP server-side implementation code, listening to the client's request, handles the data packets sent by each client in the sub-thread, and then send the process back to the client. The code provided here is very complete, including a mainclass, a monitable class, and its interface, a package processing Class, a transmission class, basically can be used directly. Some of the tools, such as DEBUG, GENPROFILE, TERMINATOR, etc., which also appear in subsequent series of articles.
Package org.kyle.net.svr.sample;
Import java.io. *;
Import java.util. *;
Import java.net. *;
Public Class Sample
{
// genprofile is a configuration file tool class that runs running parameters from the configuration file.
protected genprofile m_env = null;
protected ilistener m_listener = null;
Public Sample ()
{
String cfgfile = system.getProperty ("mainconfigfile", "server.cfg");
m_env = new genprofile (cfgfile);
}
Public Boolean StartService ()
{
Try
{
// IntegrationFactory is a factory class that creates a Listener instance
M_Listener = IntegrationFactory.createlistener (m_env);
M_Listener.SetProfile (M_ENV);
m_listener.startlistener ();
Debug.info ("Server Started.");
Return True;
}
Catch (Exception E)
{
Debug.warning (e);
}
Return False;
}
Public Boolean StopService ()
{
Try
{
m_ listener.stoplistener ();
Debug.info ("Server Service Stopped.");
Return True;
}
Catch (Exception E)
{
Debug.warning (e);
}
Return False;
}
Public static void main (String [] Argv)
{
Try
{
Sample main = new sample ();
Main.startService ();
// Terminator is used to receive the keyboard operation, and then exit after pressing the specific key.
Terminator Terminator = NULL;
Terminator = New Terminator (System.in, Main);
Terminator.start ();
Synchronized (main) {
Main.wait (); // hangs the main process until it is activated in Terminator.
Main.stopService ();
}
System.exit (0);
}
Catch (Exception E)
{
Debug.warning (e);
}
}
}
Package org.kyle.net.svr.sample;
Import java.net. *;
Public interface ilistener
{
Public void setprofile (genprofile env);
Public void listen (int port); PUBLIC VOID SETTIMEOUT (INT TIMEOUT);
Public void startlistener ();
Public void stoplistener ();
Public Rawpkt Accept ();
Public void close ();
}
Package org.kyle.net.svr.sample;
Import java.net. *;
Import java.io. *;
Import java.util. *;
Import java.math. *;
Public Class SampleListenerImpl Extends Thread Implements ILISTENER
{
PRIVATE BOOLEAN M_ISRUNNING = FALSE;
Private boolean m_innercall = false;
PRIVATE INT M_Listenat = -1;
Private int m_timeout = -1;
Private socket m_skt = NULL;
Private serversocket m_svrskt = NULL;
Public SampleListenerImpl ()
{
SetName ("SampleListener.");
}
Public SampleListenerImpl (GenProfile ENV)
Throws socketException, SecurityException, IOException
{
SetName ("SampleListener.");
IF (ENV == Null)
Throw New SecurityException ("No Environment Provided!");
M_ENV = ENV;
Invokesocket ();
}
Public void setprofile (Genprofile ENV)
{
M_ENV = ENV;
}
Public void Run ()
{
Try
{
Invokesocket ();
Debug.info ("Listening AT" M_SVRSKT.GETLOCALPORT () "...");
While (m_srunning)
{
Try
{
m_INNNERCALL = True;
Accept ();
m_innercall = false;
}
Catch (Exception E)
{
Debug.info (e);
}
}
}
Catch (Exception E)
{
Debug.info (e);
}
}
Public void startlistener ()
{
IF (! m_srunning)
{
m_srunning = true;
START ();
}
}
Public void stoplistener ()
{
IF (m_srunning)
{
m_srunning = false;
Interrupt ();
CLOSE ();
}
}
Public Rawpkt Accept ()
{
IF (m_srunning)
{
IF (m_innercall)
{}
Else
{
Debug.finest ("Standalone Listener Was Started, External Call of Accept Failed.");
Return NULL;
}
}
Try
{
m_skt = m_svrskt.accept (); m_skt.setsotimeout (m_env.gettimeout () * 1000);
Debug.fine ("ServerSocket Accepted.");
New freeelistener (m_skt);
Return NULL;
}
Catch (InterruptedioException IIOE)
{
Debug.info ("Listener Timed Out:" IIOE.GETMESSAGE () "/ n");
}
Catch (IOEXCEPTION IOE)
{
Debug.info (IOE);
}
Catch (Exception E)
{
Debug.info (e);
}
Return NULL;
}
Public void Listenon (INT Port)
{
IF (port <0 || port> 65535) Port = 0;
M_Listenat = Port;
}
Public void close ()
{
IF (m_skt! = null)
{
IF (! m_srunning)
{
Try {
m_skt.close ();
m_skt = NULL;
}
Catch (IOEXCEPTION IOE)
{
Debug.warning (IOE);
}
}
}
}
Public void setTimeout (int Timeout)
{
IF (Timeout <0) Timeout = 300;
M_TIMEOUT = TIMEOUT;
}
/ Private methods section///
Private void invokesocket ()
Throws socketException, SecurityException, IOException
{
IF (m_skt == null)
{
m_svrskt = new serversocket (m_listenat! = -1? m_listenat: m_env.getlistenat ());
m_svrskt.setsotimeout (m_timeout! = -1? m_timeout * 1000: m_env.gettimeout () * 1000);
}
}
Class Freelistener Extends Thread
{
Socket m_skt;
Public Freelistener (socket SKT)
{
m_skt = skt;
START ();
}
Public void Run ()
{
Try
{
DataInputStream is = New DataInputStream (m_skt.getinputstream ());
While (True)
{// This may receive two packages, one is an HTTP package, one is a custom package, in a custom packet, the third 4th byte is the length of this package.
BYTE [] pkthd = new byte [4];
Byte [] Rawdata = NULL;
Is.readfully (pkthd);
Boolean bushttp = false;
String method = new string (pkthd);
IF ("post") || method.equalsignorecase ("get") || method.equalsignorecase ("put") || method.equalsignorecase ("dele") || Method.EqualsignoreCase ("head") || Method.equalsignoreCase ("LINK")
|| Method.equalsignorecase ("unli"))
{
String url = is.readline ();
Debug.info ("/ NHTTP Packet Received from"
m_skt.getinetdress (). gethostaddress () ":"
m_skt.getport () "-" " Method URL);
INT LEN = 0;
IF (Method.equalsignorecase ("post"))
{
Do {
String s = is.readline ();
IF (s == NULL)
Throw new oException ("Not a http request");
IF (S.Equals ("))
Break;
INDEX = S.Indexof (':');
IF (INDEX == -1)
CONTINUE;
String name = s.substring (0, index);
String value = s.substring (Index 1);
IF ("Content-Length" .equalsignoreCase (Name.trim ())))
Len = integer.parseint (Value.trim ());
WHILE (TRUE);
Debug.Finer ("Content-length =" LEN);
}
IF (len == 0) {m_skt.close (); Break;} // must a hacker! close socket.
Rawdata = new byte [len];
Is.Readfully (Rawdata);
While (is.available ()! = 0) is.skip (is.available ());
Busehttp = true;
}
Else
{
Biginteger Bgint = New Biginteger (New Byte [] {Pkthd [2], PKTHD [3]});
INT RSTLEN = BGINT.IntValue () - 4;
IF (Rstlen <= 0)
IF (m_env.statelessService ()) Break;
Else Continue;
Debug.info ("/ NPACKET Received from ["
m_skt.getinetdress (). gethostaddress () ":"
m_skt.getport () "]; Total Len:" BGINT.InTValue ()
"REST LEN:" RSTLEN);
Rawdata = new byte [Rstlen 4]; System.ArrayCopy (pkthd, 0, rawdata, 0, 4);
Is.Readfully (Rawdata, 4, Rstlen);
Busehttp = false;
}
// Rawpkt encapsulates the package
Rawpkt npkt = new Rawpkt (Rawdata, m_skt.getinetaddress (), m_skt.getport ();
// SamplepacketHandler class is used to process the received package, and the Samplesender class is used to send data to the client.
SamplepacketHandler Handler = New SamplepacketHandler (NPKT, New Samplesender (M_SKT, M_ENV, BUSEHTTP));
Handler.start ();
Handler = NULL;
IF (m_env.statelessService ()) Break;
}
}
Catch (Exception E)
{
Debug.info (e);
}
}
}
}
Package org.kyle.net.svr.sample;
Import java.util. *;
Import java.math. *;
Public Class SamplepacketHandler Extends Thread
{
protected samplesender m_sender = null;
protected genprofile m_env = null;
Private rawpkt m_rawpkt = null;
Public SamplepacketHandler (Rawpkt Rawpkt, Genprofile Env, Samplesender Sender)
{
m_rawpkt = rawpkt;
M_ENV = ENV;
m_sender = sender;
}
Public void Run ()
{
IF (! m_sender.hasdestinfo ())
{
m_sender.setdestinationAddress (m_rawpkt.getsrcaddress ());
m_sender.SetDestinationPort (m_rawpkt.getsrcport ());
}
/ / The received packet is handled here, and the result is encapsulated in the Respkt.
m_sender.send (Respkt);
}
Package org.kyle.net.svr.sample;
Import java.net. *;
Import java.util. *;
Import java.io. *;
Public Class Samplesender
{
PRIVATE GENPROFILE M_PROFILE = NULL;
Private inetdress m_srcaddress = null;
Private int m_srcport = -1;
Private inetaddress m_dstaddress = NULL;
Private int m_dstport = -1;
Private boolean m_busehttp;
Private socket m_skt = NULL;
Public Samplesender (GenProfile Profile)
Throws socketException
{
this (null, profile);
}
Public Samplesender (socket SKT, Genprofile Profile)
Throws socketException {
THIS (SKT, Profile, False);
}
Public Samplesender (Socket Skt, Genprofile Profile, Boolean Busehttp)
Throws socketException
{
IF (Profile == Null)
Throw New SocketException ("Null Profile.");
m_skt = skt;
m_profile = profile;
m_busehttp = busehttp;
}
Public void setsourceaddRESS (inetaddress srcaddr)
{
M_SRCADDRESS = SRCADDR;
}
Public void setDestinationAddress (inetaddress dstaddr)
{
m_dstaddress = dstaddr;
}
Public void setsource (int srcport)
{
m_srcport = srcport;
}
Public Boolean HasDestinfo ()
{
Return! (m_dstaddress == NULL || m_dstport == -1 || m_dstport <= 0 || m_dstport> = 65535);
}
Public void setDestinationPort (int dstport)
{
m_dstport = dstport;
}
Public Boolean Send (InfoPacket MSG)
{
// Encode InfoPacket as a byte array
Encoder Encoder = new encoder ();
Encoder.SetProfile (M_Profile);
BYTE [] BAPKT = Encoder.Encode (MSG);
IF (BAPKT == Null ||! HasDestinfo ())
Return False;
Try
{
OutputStream OS = GetSocket (). GetOutputStream ();
IF (m_busehttp)
{
Os.write ("HTTP / 1.0 200 OK / R / NCONTENT-TYPE: TEXT / HTML / R / NCONTENT-LENGTH:" BAPKT.LENGTH "/ R / N / R / N"). getBytes ()) ;
}
Os.write (BAPKT);
Os.flush ();
IF (m_profile.statelessService ())
{
Os.Close ();
m_skt.close ();
}
Return True;
}
Catch (IOEXCEPTION IOE)
{
Debug.info (IOE);
}
Catch (Exception E)
{
Debug.info (e);
}
Return False;
}
Public inetaddress getsrcaddress ()
{
Return M_SRCADDRESS;
}
Public void setsrcaddress (inetaddress asrcaddress)
{
M_SRCADDRESS = ASRCADDRESS;
}
Public int GetSrcport ()
{
Return m_srcport;
}
Public void setsrcport (int ASRCPORT)
{
m_srcport = asrcport;
}
Private socket getsocket ()
{
IF (m_skt! = null) return m_skt;
IF (! HasDestinfo ()) Return NULL;
Try
{
IF (m_srcaddress! = null && m_srcport! = -1)
Return New Socket (m_dstaddress, m_dstport, m_srcaddress, m_srcport);
Return New Socket (M_DSTADDRESS, M_DSTPORT);
}
Catch (Socketexception SE)
{
Debug.info (se);
}
Catch (Exception E)
{
Debug.info (e);
}
Return NULL;
}
}