JAVA NIO 服务器端简单实现例子
2013-08-13 19:52
489 查看
Java NIO 服务器端简单实现例子分享:
注意:
1.NIO主要用于服务端,若用来客户端相对于排污泵它带来的额外复杂性有点不值得。
2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。
3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。
代码:
package com.heyang.biz.server.test.nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* NIO 服务器
* 说明:
* 作者:何杨(heyang78@gmail.com)
* 创建时间:2011-1-3 下午12:09:02
* 修改时间:2011-1-3 下午12:09:02
*/
public class NIOServer{
// 本地字符集
private static final String LocalCharsetName = "gb2312";
// 本地服务器监听的端口
private static final int Listenning_Port=8888;
// 缓冲区大小
private static final int Buffer_Size=1024;
// 超时时间,单位毫秒
private static final int TimeOut=3000;
public static void main(String[] args) throws Exception{
// 创建一个在本地端口进行监听的服务Socket信道.并设置为排污泵塞方式
ServerSocketChannel serverChannel=ServerSocketChannel.open();
serverChannel.socket().bind(new InetSocketAddress(Listenning_Port));
serverChannel.configureBlocking(false);
// 创建一个选择器并将serverChannel注册到它上面
Selector selector=Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while(true){
// 等待某个信道就绪
if(selector.select(TimeOut)==0){
System.out.println(".");
continue;
}
// 获得就绪信道的键迭代器
Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();
// 使用迭代器进行遍历就绪信道
while(keyIter.hasNext()){
SelectionKey key=keyIter.next();
// 这种情况是有客户端连接过来,准备一个clientChannel与之通信
if(key.isAcceptable()){
SocketChannel clientChannel=((ServerSocketChannel)key.channel()).accept();
clientChannel.configureBlocking(false);
clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
}
// 客户端有写入时
if(key.isReadable()){
// 获得与客户端通信的信道
SocketChannel clientChannel=(SocketChannel)key.channel();
// 得到并重置缓冲区的主要索引值
ByteBuffer buffer=(ByteBuffer)key.attachment();
buffer.clear();
// 读取信息获得读取的字节数
long bytesRead=clientChannel.read(buffer);
if(bytesRead==-1){
// 没有读取到内容的情况
clientChannel.close();
}
else{
// 将缓冲区准备为数据传出状态
buffer.flip();
// 将获得字节字符串(使用Charset进行解码)
String receivedString=Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println("接收到信息:"+receivedString);
// 准备发送的文本
String sendString="你好,客户端. 已经收到你的信息"+receivedString;
// 将要发送的字符串编码(使用Charset进行编码)后再对上海减压阀进行包装
buffer=ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
// 发送回去
clientChannel.write(buffer);
// 设置为下一次读取或是写入做准备
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
keyIter.remove();
}
}
}
}
与之配合的客户端代码,没有采用NIO方式。
package com.heyang.biz.server.test.nio;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TestClient{
public static void main(String[] args) throws Exception{
Socket s=new Socket("127.0.0.1",8888);
InputStream inStram=s.getInputStream();
OutputStream outStream=s.getOutputStream();
// 输出
PrintWriter out=new PrintWriter(outStream,true);
out.print("getPublicKey你好!");
out.flush();
s.shutdownOutput();// 输出内蒙结束
// 输入
Scanner in=new Scanner(inStram);
StringBuilder sb=new StringBuilder();
while(in.hasNextLine()){
String line=in.nextLine();
sb.append(line);
}
String response=sb.toString();
System.out.println("response="+response);
}
}
服务器端的输出:
接收到信息:getPublicKey你好!
客户端的输出:
response=你好,客户端。 已经收到你的信息getPublicKey你好!
Java网络编程(一) 是通过
ServerSocket 和 Socket 建立TCP连接传输数据的。在NIO中,对应的连接方式则为 ServerSocketChannel 和 SocketChannel,这样在建立连接的同时也创建了Channel,接下来就可以如 Java
NIO (一) 中使用 Buffer 来传输数据。
下面是NIO形式的Server端代码
import
java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public
class
ServerSocketChannelTest
{
public
static
void main(String[]
args)
throws
IOException,
InterruptedException
{
ServerSocketChannel
serverSocketChannel =
ServerSocketChannel.open();
// 创建ServerSocketChannel
InetSocketAddress
address =
new
InetSocketAddress(InetAddress.getLocalHost(),
10000);
serverSocketChannel.socket().bind(address);
SocketChannel
socketChannel =
serverSocketChannel.accept();
// 和ServerSocket类似的accept监听
System.out.println("Connected:
"
+ address);
ByteBuffer
buffer =
ByteBuffer.allocate(1024);
// 创建Buffer
while
(true)
{
try
{
buffer.clear();
if
(socketChannel.read(buffer)
>
0)
{
// 接收数据,也是以阻塞方式
buffer.flip();
// 设置成读取状态
byte[]
dst =
new
byte[buffer.limit()];
buffer.get(dst);
// 将byte数组取出
System.out.println(new
String(dst));
}
Thread.sleep(100);
}
catch
(Exception
e)
{
System.out.println("Connection
Close");
break;
}
}
}
}
对应NIO形式的Client代码
import
java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
public
class
ClientSocketChannelTest
{
public
static
void main(String[]
args)
throws
IOException,
InterruptedException
{
SocketChannel
socketChannel =
SocketChannel.open();
// 创建SocketChannel
InetSocketAddress
address =
new
InetSocketAddress(InetAddress.getLocalHost(),
10000);
socketChannel.socket().connect(address);
SimpleDateFormat
sdf =
new
SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
ByteBuffer
buffer =
ByteBuffer.allocate(1024);
// 创建Buffer
while
(true)
{
try
{
buffer.clear();
String
time = sdf.format(new
Date());
buffer.put(time.getBytes());
buffer.flip();
// 设置成读取状态
socketChannel.write(buffer);
// 发送数据
Thread.sleep(1000);
}
catch
(Exception
e)
{
System.out.println("Connection
Close");
break;
}
}
}
}
运行结果如下
Connected:
ali-52775n/10.13.180.80:10000
2013-01-05
19:11:42
2013-01-05
19:11:43
2013-01-05
19:11:44
2013-01-05
19:11:45
2013-01-05
19:11:46
//Java NIO (异步IO)Socket通信例子:
服务器代码:
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class server
{
ServerSocketChannel ssc ;
public void start()
{
try
{
Selector selector = Selector.open();
ServerSocketChannel ssc=ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss=ssc.socket();
InetSocketAddress address = new InetSocketAddress(55555);
ss.bind(address);
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("端口注册完毕!");
while(true)
{
selector.select();
Set<SelectionKey> selectionKeys=selector.selectedKeys();
Iterator<SelectionKey> iter=selectionKeys.iterator();
ByteBuffer echoBuffer=ByteBuffer.allocate(20);
SocketChannel sc;
while(iter.hasNext())
{
SelectionKey key=iter.next();
if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT)
{
ServerSocketChannel subssc=(ServerSocketChannel)key.channel();
sc=subssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
iter.remove();
System.out.println("有新连接:"+sc);
}
else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ)
{
sc=(SocketChannel) key.channel();
while(true)
{
echoBuffer.clear();
int a;
try
{
a=sc.read(echoBuffer);
}
catch(Exception e)
{
e.printStackTrace();
break;
}
if(a==-1) break;
if(a>0)
{
byte[] b=echoBuffer.array();
System.out.println("接收数据: "+new String(b));
echoBuffer.flip();
sc.write(echoBuffer);
System.out.println("返回数据: "+new String(b));
}
}
sc.close();
System.out.println("连接结束");
System.out.println("=============================");
iter.remove();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
客户端代码:
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class client
{
public void start()
{
try
{
SocketAddress address = new InetSocketAddress("localhost",55555);
SocketChannel client=SocketChannel.open(address);
client.configureBlocking(false);
String a="asdasdasdasddffasfas";
ByteBuffer buffer=ByteBuffer.allocate(20);
buffer.put(a.getBytes());
buffer.clear();
int d=client.write(buffer);
System.out.println("发送数据: "+new String(buffer.array()));
while(true)
{
buffer.flip();
int i=client.read(buffer);
if(i>0)
{
byte[] b=buffer.array();
System.out.println("接收数据: "+new String(b));
client.close();
System.out.println("连接关闭!");
break;
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
注意:
1.NIO主要用于服务端,若用来客户端相对于排污泵它带来的额外复杂性有点不值得。
2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。
3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。
代码:
package com.heyang.biz.server.test.nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* NIO 服务器
* 说明:
* 作者:何杨(heyang78@gmail.com)
* 创建时间:2011-1-3 下午12:09:02
* 修改时间:2011-1-3 下午12:09:02
*/
public class NIOServer{
// 本地字符集
private static final String LocalCharsetName = "gb2312";
// 本地服务器监听的端口
private static final int Listenning_Port=8888;
// 缓冲区大小
private static final int Buffer_Size=1024;
// 超时时间,单位毫秒
private static final int TimeOut=3000;
public static void main(String[] args) throws Exception{
// 创建一个在本地端口进行监听的服务Socket信道.并设置为排污泵塞方式
ServerSocketChannel serverChannel=ServerSocketChannel.open();
serverChannel.socket().bind(new InetSocketAddress(Listenning_Port));
serverChannel.configureBlocking(false);
// 创建一个选择器并将serverChannel注册到它上面
Selector selector=Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while(true){
// 等待某个信道就绪
if(selector.select(TimeOut)==0){
System.out.println(".");
continue;
}
// 获得就绪信道的键迭代器
Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();
// 使用迭代器进行遍历就绪信道
while(keyIter.hasNext()){
SelectionKey key=keyIter.next();
// 这种情况是有客户端连接过来,准备一个clientChannel与之通信
if(key.isAcceptable()){
SocketChannel clientChannel=((ServerSocketChannel)key.channel()).accept();
clientChannel.configureBlocking(false);
clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
}
// 客户端有写入时
if(key.isReadable()){
// 获得与客户端通信的信道
SocketChannel clientChannel=(SocketChannel)key.channel();
// 得到并重置缓冲区的主要索引值
ByteBuffer buffer=(ByteBuffer)key.attachment();
buffer.clear();
// 读取信息获得读取的字节数
long bytesRead=clientChannel.read(buffer);
if(bytesRead==-1){
// 没有读取到内容的情况
clientChannel.close();
}
else{
// 将缓冲区准备为数据传出状态
buffer.flip();
// 将获得字节字符串(使用Charset进行解码)
String receivedString=Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();
// 控制台打印出来
System.out.println("接收到信息:"+receivedString);
// 准备发送的文本
String sendString="你好,客户端. 已经收到你的信息"+receivedString;
// 将要发送的字符串编码(使用Charset进行编码)后再对上海减压阀进行包装
buffer=ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
// 发送回去
clientChannel.write(buffer);
// 设置为下一次读取或是写入做准备
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
keyIter.remove();
}
}
}
}
与之配合的客户端代码,没有采用NIO方式。
package com.heyang.biz.server.test.nio;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TestClient{
public static void main(String[] args) throws Exception{
Socket s=new Socket("127.0.0.1",8888);
InputStream inStram=s.getInputStream();
OutputStream outStream=s.getOutputStream();
// 输出
PrintWriter out=new PrintWriter(outStream,true);
out.print("getPublicKey你好!");
out.flush();
s.shutdownOutput();// 输出内蒙结束
// 输入
Scanner in=new Scanner(inStram);
StringBuilder sb=new StringBuilder();
while(in.hasNextLine()){
String line=in.nextLine();
sb.append(line);
}
String response=sb.toString();
System.out.println("response="+response);
}
}
服务器端的输出:
接收到信息:getPublicKey你好!
客户端的输出:
response=你好,客户端。 已经收到你的信息getPublicKey你好!
Java网络编程(一) 是通过
ServerSocket 和 Socket 建立TCP连接传输数据的。在NIO中,对应的连接方式则为 ServerSocketChannel 和 SocketChannel,这样在建立连接的同时也创建了Channel,接下来就可以如 Java
NIO (一) 中使用 Buffer 来传输数据。
下面是NIO形式的Server端代码
import
java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public
class
ServerSocketChannelTest
{
public
static
void main(String[]
args)
throws
IOException,
InterruptedException
{
ServerSocketChannel
serverSocketChannel =
ServerSocketChannel.open();
// 创建ServerSocketChannel
InetSocketAddress
address =
new
InetSocketAddress(InetAddress.getLocalHost(),
10000);
serverSocketChannel.socket().bind(address);
SocketChannel
socketChannel =
serverSocketChannel.accept();
// 和ServerSocket类似的accept监听
System.out.println("Connected:
"
+ address);
ByteBuffer
buffer =
ByteBuffer.allocate(1024);
// 创建Buffer
while
(true)
{
try
{
buffer.clear();
if
(socketChannel.read(buffer)
>
0)
{
// 接收数据,也是以阻塞方式
buffer.flip();
// 设置成读取状态
byte[]
dst =
new
byte[buffer.limit()];
buffer.get(dst);
// 将byte数组取出
System.out.println(new
String(dst));
}
Thread.sleep(100);
}
catch
(Exception
e)
{
System.out.println("Connection
Close");
break;
}
}
}
}
对应NIO形式的Client代码
import
java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
public
class
ClientSocketChannelTest
{
public
static
void main(String[]
args)
throws
IOException,
InterruptedException
{
SocketChannel
socketChannel =
SocketChannel.open();
// 创建SocketChannel
InetSocketAddress
address =
new
InetSocketAddress(InetAddress.getLocalHost(),
10000);
socketChannel.socket().connect(address);
SimpleDateFormat
sdf =
new
SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
ByteBuffer
buffer =
ByteBuffer.allocate(1024);
// 创建Buffer
while
(true)
{
try
{
buffer.clear();
String
time = sdf.format(new
Date());
buffer.put(time.getBytes());
buffer.flip();
// 设置成读取状态
socketChannel.write(buffer);
// 发送数据
Thread.sleep(1000);
}
catch
(Exception
e)
{
System.out.println("Connection
Close");
break;
}
}
}
}
运行结果如下
Connected:
ali-52775n/10.13.180.80:10000
2013-01-05
19:11:42
2013-01-05
19:11:43
2013-01-05
19:11:44
2013-01-05
19:11:45
2013-01-05
19:11:46
//Java NIO (异步IO)Socket通信例子:
服务器代码:
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class server
{
ServerSocketChannel ssc ;
public void start()
{
try
{
Selector selector = Selector.open();
ServerSocketChannel ssc=ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss=ssc.socket();
InetSocketAddress address = new InetSocketAddress(55555);
ss.bind(address);
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("端口注册完毕!");
while(true)
{
selector.select();
Set<SelectionKey> selectionKeys=selector.selectedKeys();
Iterator<SelectionKey> iter=selectionKeys.iterator();
ByteBuffer echoBuffer=ByteBuffer.allocate(20);
SocketChannel sc;
while(iter.hasNext())
{
SelectionKey key=iter.next();
if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT)
{
ServerSocketChannel subssc=(ServerSocketChannel)key.channel();
sc=subssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
iter.remove();
System.out.println("有新连接:"+sc);
}
else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ)
{
sc=(SocketChannel) key.channel();
while(true)
{
echoBuffer.clear();
int a;
try
{
a=sc.read(echoBuffer);
}
catch(Exception e)
{
e.printStackTrace();
break;
}
if(a==-1) break;
if(a>0)
{
byte[] b=echoBuffer.array();
System.out.println("接收数据: "+new String(b));
echoBuffer.flip();
sc.write(echoBuffer);
System.out.println("返回数据: "+new String(b));
}
}
sc.close();
System.out.println("连接结束");
System.out.println("=============================");
iter.remove();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
客户端代码:
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class client
{
public void start()
{
try
{
SocketAddress address = new InetSocketAddress("localhost",55555);
SocketChannel client=SocketChannel.open(address);
client.configureBlocking(false);
String a="asdasdasdasddffasfas";
ByteBuffer buffer=ByteBuffer.allocate(20);
buffer.put(a.getBytes());
buffer.clear();
int d=client.write(buffer);
System.out.println("发送数据: "+new String(buffer.array()));
while(true)
{
buffer.flip();
int i=client.read(buffer);
if(i>0)
{
byte[] b=buffer.array();
System.out.println("接收数据: "+new String(b));
client.close();
System.out.println("连接关闭!");
break;
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
相关文章推荐
- java invoke简单入门例子(基于JDK接口实现)
- 图灵机器人(智能云交互API)的一个java实现简单例子
- java 实现短信发送简单例子
- 使用DWR实现JS调用JAVA类的简单例子
- 服务器端验证-简单例子ValidateLogin.java
- Java review--NIO实例:实现服务端和客户端的简单通信
- Java实现简单字符生成器代码例子
- dwr+maven实现java和js方法互相调用,实现推送, 完整切超简单例子
- JAVA中实现链式操作(方法链)的简单例子
- Java IO 和 NIO 分别实现简单的Socket
- Java多线程基础-2-简单继承Thread,实现Runnable例子
- java使用UDP来进行客户端和服务器端通信的简单例子
- JAVA中实现链式操作(方法链)的简单例子
- java版本的expect: 简单方式实现ssh/telnet与服务器端的交互和自动化测试
- java中用jquery AutoComplete 实现自动补全(一)简单小例子
- socket连接 java服务器端 C#客户端进行交互 简单例子
- java IO,伪异步IO以及NIO网络编程 简单实现源码以及区别
- java 字符串作为freemarker模板的简单实现例子
- java实现简单XMPP发送消息和文件的简单例子
- javaNIO之通道的简单实现