Java Socket Practice 6 Use NiO package for socket communication

Source: Internet
Author: User

Address: http://blog.csdn.net/kongxx/article/details/7288896

The previous articles introduced socket communication using Java. Io and java.net class libraries. The following describes the socket implemented using the java. Nio class library.

The Java. Nio package is added after Java 1.4 to improve the efficiency of I/O operations. The NiO package mainly includes the following classes or interfaces:

* Buffer: a buffer used to temporarily store input or output data.

* Charset: used to convert UNICODE character encoding and other character encoding.

* Channel: a data transmission channel used to write data in the buffer to the data source or read data from the data source to the buffer.

* Selector: used to support asynchronous I/O operations, also called non-blocking I/O operations.

The NiO package mainly improves the I/O operation efficiency through the following two aspects:

* The buffer and channel are used to increase the speed of I/O operations.

* Selector is used to support non-blocking I/O operations.

The following describes how to implement the socket function through these class libraries in the program.

First, we will introduce several helper classes.

The auxiliary class serializableutil is used to serialize Java objects into byte arrays or deserialize byte arrays into Java objects.

package com.googlecode.garbagecan.test.socket;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class SerializableUtil {public static byte[] toBytes(Object object) {ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(baos);oos.writeObject(object);byte[] bytes = baos.toByteArray();return bytes;} catch(IOException ex) {throw new RuntimeException(ex.getMessage(), ex);} finally {try {oos.close();} catch (Exception e) {}}}public static Object toObject(byte[] bytes) {ByteArrayInputStream bais = new ByteArrayInputStream(bytes);ObjectInputStream ois = null;try {ois = new ObjectInputStream(bais);Object object = ois.readObject();return object;} catch(IOException ex) {throw new RuntimeException(ex.getMessage(), ex);} catch(ClassNotFoundException ex) {throw new RuntimeException(ex.getMessage(), ex);} finally {try {ois.close();} catch (Exception e) {}}}}

The auxiliary classes myrequestobject and myresponseobject are common Java objects and implement the serializable interface. The myrequestobject class is the request sent by the client, and myresponseobject is the response made by the server.

package com.googlecode.garbagecan.test.socket.nio;import java.io.Serializable;public class MyRequestObject implements Serializable {private static final long serialVersionUID = 1L;private String name;private String value;private byte[] bytes;public MyRequestObject(String name, String value) {this.name = name;this.value = value;this.bytes = new byte[1024];}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}@Overridepublic String toString() {StringBuffer sb = new StringBuffer();sb.append("Request [name: " + name  + ", value: " + value + ", bytes: " + bytes.length+ "]");return sb.toString();}}package com.googlecode.garbagecan.test.socket.nio;import java.io.Serializable;public class MyResponseObject implements Serializable {private static final long serialVersionUID = 1L;private String name;private String value;private byte[] bytes;public MyResponseObject(String name, String value) {this.name = name;this.value = value;this.bytes = new byte[1024];}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}@Overridepublic String toString() {StringBuffer sb = new StringBuffer();sb.append("Response [name: " + name  + ", value: " + value + ", bytes: " + bytes.length+ "]");return sb.toString();}}

Next, let's take a look at the server code. Some of the English comments are helpful for understanding the code. The comments are mainly from the JDK documentation and examples.

package com.googlecode.garbagecan.test.socket.nio;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.ClosedChannelException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;import com.googlecode.garbagecan.test.socket.SerializableUtil;public class MyServer3 {private final static Logger logger = Logger.getLogger(MyServer3.class.getName());public static void main(String[] args) {Selector selector = null;ServerSocketChannel serverSocketChannel = null;try {// Selector for incoming time requestsselector = Selector.open();// Create a new server socket and set to non blocking modeserverSocketChannel = ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);// Bind the server socket to the local host and portserverSocketChannel.socket().setReuseAddress(true);serverSocketChannel.socket().bind(new InetSocketAddress(10000));// Register accepts on the server socket with the selector. This// step tells the selector that the socket wants to be put on the// ready list when accept operations occur, so allowing multiplexed// non-blocking I/O to take place.serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// Here's where everything happens. The select method will// return when any operations registered above have occurred, the// thread has been interrupted, etc.while (selector.select() > 0) {// Someone is ready for I/O, get the ready keysIterator<SelectionKey> it = selector.selectedKeys().iterator();// Walk through the ready keys collection and process date requests.while (it.hasNext()) {SelectionKey readyKey = it.next();it.remove();// The key indexes into the selector so you// can retrieve the socket that's ready for I/Oexecute((ServerSocketChannel) readyKey.channel());}}} catch (ClosedChannelException ex) {logger.log(Level.SEVERE, null, ex);} catch (IOException ex) {logger.log(Level.SEVERE, null, ex);} finally {try {selector.close();} catch(Exception ex) {}try {serverSocketChannel.close();} catch(Exception ex) {}}}private static void execute(ServerSocketChannel serverSocketChannel) throws IOException {SocketChannel socketChannel = null;try {socketChannel = serverSocketChannel.accept();MyRequestObject myRequestObject = receiveData(socketChannel);logger.log(Level.INFO, myRequestObject.toString());MyResponseObject myResponseObject = new MyResponseObject("response for " + myRequestObject.getName(), "response for " + myRequestObject.getValue());sendData(socketChannel, myResponseObject);logger.log(Level.INFO, myResponseObject.toString());} finally {try {socketChannel.close();} catch(Exception ex) {}}}private static MyRequestObject receiveData(SocketChannel socketChannel) throws IOException {MyRequestObject myRequestObject = null;ByteArrayOutputStream baos = new ByteArrayOutputStream();ByteBuffer buffer = ByteBuffer.allocate(1024);try {byte[] bytes;int size = 0;while ((size = socketChannel.read(buffer)) >= 0) {buffer.flip();bytes = new byte[size];buffer.get(bytes);baos.write(bytes);buffer.clear();}bytes = baos.toByteArray();Object obj = SerializableUtil.toObject(bytes);myRequestObject = (MyRequestObject)obj;} finally {try {baos.close();} catch(Exception ex) {}}return myRequestObject;}private static void sendData(SocketChannel socketChannel, MyResponseObject myResponseObject) throws IOException {byte[] bytes = SerializableUtil.toBytes(myResponseObject);ByteBuffer buffer = ByteBuffer.wrap(bytes);socketChannel.write(buffer);}}

The following is the client code. The code is simple: 100 threads are started to access the server.

package com.googlecode.garbagecan.test.socket.nio;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;import java.util.logging.Level;import java.util.logging.Logger;import com.googlecode.garbagecan.test.socket.SerializableUtil;public class MyClient3 {private final static Logger logger = Logger.getLogger(MyClient3.class.getName());public static void main(String[] args) throws Exception {for (int i = 0; i < 100; i++) {final int idx = i;new Thread(new MyRunnable(idx)).start();}}private static final class MyRunnable implements Runnable {private final int idx;private MyRunnable(int idx) {this.idx = idx;}public void run() {SocketChannel socketChannel = null;try {socketChannel = SocketChannel.open();SocketAddress socketAddress = new InetSocketAddress("localhost", 10000);socketChannel.connect(socketAddress);MyRequestObject myRequestObject = new MyRequestObject("request_" + idx, "request_" + idx);logger.log(Level.INFO, myRequestObject.toString());sendData(socketChannel, myRequestObject);MyResponseObject myResponseObject = receiveData(socketChannel);logger.log(Level.INFO, myResponseObject.toString());} catch (Exception ex) {logger.log(Level.SEVERE, null, ex);} finally {try {socketChannel.close();} catch(Exception ex) {}}}private void sendData(SocketChannel socketChannel, MyRequestObject myRequestObject) throws IOException {byte[] bytes = SerializableUtil.toBytes(myRequestObject);ByteBuffer buffer = ByteBuffer.wrap(bytes);socketChannel.write(buffer);socketChannel.socket().shutdownOutput();}private MyResponseObject receiveData(SocketChannel socketChannel) throws IOException {MyResponseObject myResponseObject = null;ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ByteBuffer buffer = ByteBuffer.allocateDirect(1024);byte[] bytes;int count = 0;while ((count = socketChannel.read(buffer)) >= 0) {buffer.flip();bytes = new byte[count];buffer.get(bytes);baos.write(bytes);buffer.clear();}bytes = baos.toByteArray();Object obj = SerializableUtil.toObject(bytes);myResponseObject = (MyResponseObject) obj;socketChannel.socket().shutdownInput();} finally {try {baos.close();} catch(Exception ex) {}}return myResponseObject;}}}

Finally, test the above Code. First, run the server class, and then run the client class. Then, you can view the sent or received myrequestobject or myresponseobject object on the server and client console respectively.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.