📄 deitelmessengernonblockingserver.java
字号:
// Fig. 18.X: DeitelMessengerNonBlockingServer.java
// Set up a nonblocking chatServer that will receive a connection from a
// client and echo client's message to all connected clients.
package com.deitel.messenger.sockets.server;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
public class DeitelMessengerNonBlockingServer extends JFrame {
private ServerSocketChannel serverSocketChannel;
private Selector selector;
private Vector sockets = new Vector();
private int counter = 0;
private JTextArea displayArea;
private Charset charSet;
private ByteBuffer writeBuffer;
private ByteBuffer readBuffer = ByteBuffer.allocate( 512 );
public DeitelMessengerNonBlockingServer()
{
super( "DeitelMessenger Server" );
displayArea = new JTextArea();
getContentPane().add( new JScrollPane( displayArea ) );
setSize( 200, 300 );
setVisible( true );
// close server socket channel and selector when closing window
addWindowListener(
new WindowAdapter() {
public void windowClosing( WindowEvent windowEvent )
{
// close server socket channel and selector
try {
serverSocketChannel.close();
selector.close();
}
catch( IOException ioException ) {
ioException.printStackTrace();
}
finally {
System.exit( 0 );
}
}
} // end inner class WindowAdapter
); // end addWindowListener
} // end constructor
// set up and run server
public void runServer()
{
// set up server to receive connections; process connections
try {
// specify the char set used to encode/decode messages
charSet = Charset.forName( "UTF-8" );
// create a ServerSocketChannel.
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(
new InetSocketAddress( 12345 ) );
serverSocketChannel.configureBlocking( false );
// wait for a connection.
getConnection();
} // end try
// process problems with I/O
catch ( Exception ioException ) {
ioException.printStackTrace();
}
} // end method runServer
// wait for connection to arrive, then display connection info
private void getConnection() throws Exception
{
// Selector for incoming requests
selector = SelectorProvider.provider().openSelector();
serverSocketChannel.register(
selector, SelectionKey.OP_ACCEPT, null );
// process incoming requests
while ( selector.select() > 0 ) {
// get channels ready for i/o
Set readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
// for each ready channel, process request
while ( iterator.hasNext() ) {
SelectionKey key = ( SelectionKey )iterator.next();
iterator.remove();
if ( key.isAcceptable() ) { // ready for connection
// create connection
ServerSocketChannel nextReady =
( ServerSocketChannel ) key.channel();
SocketChannel socketChannel = nextReady.accept();
if ( socketChannel != null ) {
socketChannel.configureBlocking( false );
sockets.add( socketChannel.socket() );
counter++;
SwingUtilities.invokeLater(
new Runnable() {
public void run()
{
displayArea.append(
"\nConnection with Client " + counter );
}
}
);
// register read operation to socketChannel
SelectionKey readKey = socketChannel.register(
selector, SelectionKey.OP_READ, null );
} // end if socketChannel != null
} // end if key.isAcceptable
else if ( key.isReadable() ) { // ready for read
// get socketChannel ready for read
SocketChannel socketChannel =
( SocketChannel ) key.channel();
readMessage( socketChannel );
}
} // end processing each channel
} // end processing incoming requests
} // end method getConnection
// send message to client
private void writeMessage( String message ) throws IOException
{
Socket socket;
SocketChannel socketChannel;
// echo message back to all connected clients
for ( int i = 0; i < sockets.size(); i++ ) {
socket = ( Socket ) sockets.elementAt( i );
socketChannel = socket.getChannel();
// send message to client
try {
// convert message to bytes in charSet
writeBuffer = charSet.encode( message );
// write message to socketChannel
socketChannel.write( writeBuffer );
}
// process problems sending object
catch ( IOException ioException ) {
ioException.printStackTrace();
socketChannel.close();
sockets.remove( socket );
}
} // end for
} // end method writeMessage
// read message from client
private void readMessage( SocketChannel socketChannel )
throws IOException
{
// read message
try {
if ( socketChannel.isOpen() ) {
readBuffer.clear();
socketChannel.read( readBuffer );
readBuffer.flip();
CharBuffer charMessage = charSet.decode( readBuffer );
String message = charMessage.toString().trim();
// remove and close the connection when client disconnects
if ( message.indexOf( "Disconnect" ) >= 0 ) {
sockets.remove( socketChannel.socket() );
socketChannel.close();
}
else
writeMessage( message );
} // end if
} // end try
catch ( IOException ioException ) {
ioException.printStackTrace();
sockets.remove( socketChannel.socket() );
socketChannel.close();
}
} // end method readMessage
public static void main( String args[] )
{
DeitelMessengerNonBlockingServer application =
new DeitelMessengerNonBlockingServer();
application.runServer();
}
} // end class DeitelMessengerNonBlockingServer
/**************************************************************************
* (C) Copyright 1992-2003 by Deitel & Associates, Inc. and *
* Prentice Hall. All Rights Reserved. *
* *
* DISCLAIMER: The authors and publisher of this book have used their *
* best efforts in preparing the book. These efforts include the *
* development, research, and testing of the theories and programs *
* to determine their effectiveness. The authors and publisher make *
* no warranty of any kind, expressed or implied, with regard to these *
* programs or to the documentation contained in these books. The authors *
* and publisher shall not be liable in any event for incidental or *
* consequential damages in connection with, or arising out of, the *
* furnishing, performance, or use of these programs. *
*************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -