/**
* Fly_m at 2009-5-20
*/
Package com. m_ylf.study.nio;
Import java. Io. file;
Import java. Io. fileinputstream;
Import java.net. inetsocketaddress;
Import java. NiO. bytebuffer;
Import java. NiO. channels .*;
Import java. util. hashmap;
Import java. util. iterator;
Import java. util. Map;
Import java. util. Concurrent. callable;
/** @ Author fly_m */
// Simulate download service
Public class downloadserver <t> implements callable <t> {
Private selector; // create a global Selector
Private Map <socketchannel, handle> map = new hashmap <socketchannel, handle> (); // ing between socketchannel and handle
// Create a server serversocketchannel and register it with Selector
Public downloadserver () throws exception {
Selector = selector. open ();
Serversocketchannel = serversocketchannel. open ();
Serversocketchannel. configureblocking (false );
Serversocketchannel. socket (). BIND (New inetsocketaddress (1234 ));
Serversocketchannel. Register (selector, selectionkey. op_accept );
}
// Iterate selector. Select and process them in sequence
Public t call () throws exception {
System. Out. println ("startto listen in 1234 ....");
For (;{
Selector. Select ();
Iterator <selectionkey> keyiterator = selector. selectedkeys (). iterator ();
While (keyiterator. hasnext ()){
Selectionkey key = keyiterator. Next ();
If (key. isvalid ())
Handle (key );
Keyiterator. Remove ();
}
}
}
// Process each key. The primary class processes the acceptable key, and other events are processed by the internal class.
Private void handle (final selectionkey key) throws exception {
If (key. isacceptable ()){
Serversocketchannel channel = (serversocketchannel) Key. Channel ();
Socketchannel = channel. Accept ();
Socketchannel. configureblocking (false );
Socketchannel. Register (selector, selectionkey. op_read); // register a read event
Map. Put (socketchannel, new handle (); // bind the socket and handle.
}
// Use handle in map to process read and write events to simulate simultaneous download of multiple files
If (key. isreadable () | key. iswritable ()){
Socketchannel = (socketchannel) Key. Channel ();
Final handle = map. Get (socketchannel );
If (handle! = NULL)
Handle. Handle (key );
}
}
// Internal class. Simulate an internal class to process a file download service. Multiple classes can process multiple file download services.
Private class handle {
Private stringbuilder message;
Private Boolean writeok = true;
Private bytebuffer = bytebuffer. Allocate (1024 );
Private filechannel;
Private string filename;
Private void handle (selectionkey key) throws exception {
If (key. isreadable ()){
Socketchannel = (socketchannel) Key. Channel ();
If (writeok)
Message = new stringbuilder ();
While (true ){
Bytebuffer. Clear ();
Int r = socketchannel. Read (bytebuffer );
If (r = 0)
Break;
If (r =-1 ){
Socketchannel. Close ();
Key. Cancel ();
Return;
}
Message. append (new string (bytebuffer. Array (), 0, R ));
}
// Convert received information into a file name to map to a specified file on the server
If (writeok & invokemessage (Message )){
Socketchannel. Register (selector, selectionkey. op_write );
Writeok = false;
}
}
// Write data to the client
If (key. iswritable ()){
If (! Key. isvalid ())
Return;
Socketchannel = (socketchannel) Key. Channel ();
If (filechannel = NULL)
Filechannel = new fileinputstream (filename). getchannel ();
Bytebuffer. Clear ();
Int W = filechannel. Read (bytebuffer );
// If the file has been written, turn off the key and Socket
If (W <= 0 ){
Filename = NULL;
Filechannel. Close ();
Filechannel = NULL;
Writeok = true;
Socketchannel. Close ();
Key. Channel ();
Return;
}
Bytebuffer. Flip ();
Socketchannel. Write (bytebuffer );
}
}
// Convert the information into a file name
Private Boolean invokemessage (stringbuilder message ){
String M = message. tostring ();
Try {
File F = new file (m );
If (! F. exists ())
Return false;
Filename = m;
Return true;
} Catch (exception e ){
Return false;
}
}
}
Public static void main (string [] ARGs) throws exception {
/*
Executorservice = executors. newsinglethreadexecutor ();
Executorservice. Submit (New downloadserver <Object> ());
Executorservice. Shutdown ();
*/
New downloadserver (). Call ();
}
}
/*** Fly_m at 2009-5-20 */package COM. m_ylf.study.nio; import Java. io. randomaccessfile; import Java. NIO. bytebuffer; import Java. NIO. channels. filechannel; import Java. NIO. channels. selectionkey; import Java. NIO. channels. selector; import Java. NIO. channels. socketchannel; import Java. util. iterator; import Java. util. concurrent. callable; import Java. util. concurrent. executorservice; import Java. util. concurrent. exec Utors; import java.net. inetsocketaddress;/** @ author fly_m * // simulate the download of the public class downloadclient <t> implements callable <t> {private filechannel; Private Static selector; private bytebuffer = bytebuffer. allocate (1024); Private string serverfilename; // file private string localfilename on the server; // file name downloaded to the client public downloadclient (string serverfilename, string localfilename) {This. s Erverfilename = serverfilename; this. localfilename = localfilename;} public t call () throws exception {// enable selector and establish a socket connection to the specified port if (selector = NULL) selector = selector. open (); socketchannel channel = socketchannel. open (); channel. configureblocking (false); channel. connect (New inetsocketaddress ("localhost", 1234); channel. register (selector, selectionkey. op_connect); // read the information for (; {selector. select (); I Terator <selectionkey> keyiterator = selector. selectedkeys (). iterator (); While (keyiterator. hasnext () {selectionkey key = keyiterator. next (); keyiterator. remove (); // connection event if (key. isconnectable () {socketchannel = (socketchannel) Key. channel (); If (socketchannel. isconnectionpending () socketchannel. finishconnect (); socketchannel. write (bytebuffer. wrap (serverfilename. getbytes (); // sends a message to the server, which is a service in the information File Name of the socketchannel. register (selector, selectionkey. op_read);} // read event if (key. isreadable () {socketchannel = (socketchannel) Key. channel (); bytebuffer. clear (); If (! Socketchannel. isconnected () return NULL; // download the created file channelif (filechannel = NULL) filechannel = new randomaccessfile (localfilename, "RW") to the local machine "). getchannel (); int r = socketchannel. read (bytebuffer); // if the file is downloaded, turn off the channel and turn off socketchannelif (r <= 0) {If (filechannel! = NULL) filechannel. close (); channel. close (); key. cancel (); return NULL;} bytebuffer. flip (); // write it to filechannel In the downloaded file. write (bytebuffer) ;}}}// the client downloads files to the server using 10 threads and saves them as public static void main (string [] ARGs) of different files) throws exception {executorservice = executors. newsinglethreadexecutor (); For (INT I = 0; I <10; I ++) {executorservice. submit (New downloadclient <Object> ("D:/log4j. log "," d:/down "+ I + ". log ");} executorservice. shutdown ();}}