Java使用NIO包实现Socket通信的实例代码
发布时间:2020-05-23 05:53:09 所属栏目:Java 来源:互联网
导读:前面几篇文章介绍了使用java.io和java.net类库实现的Socket通信,下面介绍一下使用java.nio类库实现的Socket。
|
前面几篇文章介绍了使用java.io和java.net类库实现的Socket通信,下面介绍一下使用java.nio类库实现的Socket。 java.nio包是Java在1.4之后增加的,用来提高I/O操作的效率。在nio包中主要包括以下几个类或接口:
nio包中主要通过下面两个方面来提高I/O操作效率:
下面来看一下程序中是怎么通过这些类库实现Socket功能。 首先介绍一下几个辅助类 辅助类SerializableUtil,这个类用来把java对象序列化成字节数组,或者把字节数组反序列化成java对象。
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) {}
}
}
}
辅助类MyRequestObject和MyResponSEObject,这两个类是普通的java对象,实现了Serializable接口。MyRequestObject类是Client发出的请求,MyResponSEObject是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;
}
@Override
public 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;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Response [name: " + name + ",bytes: " + bytes.length+ "]");
return sb.toString();
}
}
下面主要看一下Server端的代码,其中有一些英文注释对理解代码很有帮助,注释主要是来源jdk的文档和例子,这里就没有再翻译
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 requests
selector = Selector.open();
// Create a new server socket and set to non blocking mode
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
// Bind the server socket to the local host and port
serverSocketChannel.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 keys
Iterator<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/O
execute((ServerSocketChannel) readyKey.channel());
}
}
} catch (ClosedChannelException ex) {
logger.log(Level.SEVERE,null,ex);
} catch (IOException ex) {
logger.log(Level.SEVERE,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);
}
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
