关闭

Java review--NIO实例:实现服务端和客户端的简单通信

标签: NIO
718人阅读 评论(4) 收藏 举报
分类:


客户端代码:

package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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.util.Iterator;
import java.util.Set;

public class NIOServer {
	
	private int flag =1;
	private int blockSize=4096;
	private ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//发送数据缓冲区
	private ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收数据缓冲区
	private Selector selector;//选择器
	
	
	public NIOServer(int port) throws IOException{
		ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
		//设置是否组阻塞
		serverSocketChannel.configureBlocking(false);
		//创建客户端和服务端的socket.socket网络套接字,用来向网络发送请求,或者应答请求。
		ServerSocket serverSocket=serverSocketChannel.socket();
		//绑定socket地址,IP端口
		serverSocket.bind(new InetSocketAddress(port));
		//打开筛选器
		selector=Selector.open();
		
		// 将选择器绑定到监听信道,只有非阻塞信道才可以注册选择器.并在注册过程中指出该信道可以进行Accept操作,返回key
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		System.out.println("Server start ->"+port);
	}
	
	//NIOServer的监听事件
	public void listen() throws IOException{
		while(true){
			selector.select();
			Set<SelectionKey> selectionKeys=selector.selectedKeys();
			Iterator<SelectionKey> itetor=selectionKeys.iterator();
			while(itetor.hasNext()){
				//负责多线程并发的安全的key
				SelectionKey selectionKey=itetor.next();
				itetor.remove();
				//业务逻辑
				handleKey(selectionKey);
			}
		}
	}
	
	
	//业务逻辑
	public void handleKey(SelectionKey selectionKey) throws IOException{
		//服务端监听通道
		ServerSocketChannel server=null;
		SocketChannel client=null;
		String reciveText;
		String sendText;
		int count=0;
		if(selectionKey.isAcceptable()){
			//服务端接收客户端信息
			server=(ServerSocketChannel)selectionKey.channel();
			client=server.accept();
			client.configureBlocking(false);
			client.register(selector, selectionKey.OP_READ);
		}else if(selectionKey.isReadable()){
			//服务端读取客户端信息
			client =(SocketChannel)selectionKey.channel();
			count =client.read(receivebuffer);
			if(count>0){
				reciveText =new String(receivebuffer.array(),0,count);
				System.out.println("服务端接收到客户端的信息:"+reciveText);
				client.register(selector,selectionKey.OP_WRITE);
			}
		}else if (selectionKey.isWritable()){
			//服务端发送数据给客户端
			sendbuffer.clear();
			client=(SocketChannel)selectionKey.channel();
			sendText="mag send to client:"+flag++;
			sendbuffer.put(sendText.getBytes());
			sendbuffer.flip();
			client.write(sendbuffer);
			System.out.println("服务端发送数据给客户端:"+sendText);
			
		}
		
	}
	
	public static void main(String[] args) throws IOException {
		int port =7080;
		NIOServer server =new NIOServer(port);
		server.listen();
	}
	
	
	
}




服务端代码:

package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOClient {
	private static  int flag =1;
	private static int blockSize=4096;
	private static ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//发送数据缓冲区
	private static  ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收数据缓冲区
	
	//Socket地址:ip+端口
	private final static InetSocketAddress serverAddress=new InetSocketAddress("127.0.0.1",7080);
	
	public static void main(String[] args) throws IOException {
		//打开通道
		SocketChannel socketChannel=SocketChannel.open();
		//通道设置成非阻塞模式
		socketChannel.configureBlocking(false);
		//打开筛选器
		Selector selector =Selector.open();
		//注册选择器
		socketChannel.register(selector, SelectionKey.OP_CONNECT);
		socketChannel.connect(serverAddress);
		
		Set<SelectionKey> selectionKeys;
		Iterator<SelectionKey> iterator;
		SelectionKey selectionKey;
		SocketChannel client;
		String receiveTest;
		String sendText;
		int count=0;		
		while(true){
			selectionKeys =selector.selectedKeys();
			iterator=selectionKeys.iterator();
			while(iterator.hasNext()){
				selectionKey=iterator.next();
				if(selectionKey.isConnectable()){
					System.out.println("client connect");
					client =(SocketChannel)selectionKey.channel();
					if(client.isConnectionPending()){
						client.finishConnect();
						System.out.println("客户端完成连接操作!");
						sendbuffer.clear();
						sendbuffer.put("Hello,Server".getBytes());
						sendbuffer.flip();
						client.write(sendbuffer);
					}
					client.register(selector, SelectionKey.OP_READ);
					
				}if(selectionKey.isReadable()){
						client=(SocketChannel)selectionKey.channel();
						receivebuffer.clear();
						count=client.read(receivebuffer);
						if(count>0){
							receiveTest =new String(receivebuffer.array(),0,count);
							System.out.println("客户端接收到服务端的数据:"+receiveTest);
							client.register(selector,SelectionKey.OP_WRITE);
							
						}
				}if(selectionKey.isWritable()){
					sendbuffer.clear();
					client=(SocketChannel)selectionKey.channel();
					sendText="Msg from client--->"+flag++;
					sendbuffer.put(sendText.getBytes());
					sendbuffer.flip();
					client.write(sendbuffer);
					System.out.println("客户端发送方数据给服务端:"+sendText);
					client.register(selector, SelectionKey.OP_READ);
					
				}
				}
			
			selectionKeys.clear();
			}
		}
	}



0
0
查看评论

Socket+NIO实现客户端与服务器的通信的Demo

之前在写一个即使通讯软件的时候使用了阻塞式IO来完成通讯,在服务器对于没一个客户端的链接,服务器都要启动一个线程来维持客户端的阻塞。虽然我使用了线程池来优化线程的开销,但难免还是有性能上的瓶颈
  • canot
  • canot
  • 2016-05-11 10:58
  • 4442

java nio Selector的使用-客户端

java nio Selector的使用-客户端<br />  接上一篇,客户端的程序就相对于简单了,只需要负责连接,发送下载文件名,再读数据就行了。主要步骤就是注册->连接服务器->发送下载请求->读数据->断开连接。<br />  第一步:注册,并...
  • kangojian
  • kangojian
  • 2010-07-03 22:19
  • 6364

java nio Selector的使用-客户端

java nio Selector的使用-客户端   接上一篇,客户端的程序就相对于简单了,只需要负责连接,发送下载文件名,再读数据就行了。主要步骤就是注册->连接服务器->发送下载请求->读数据->断开连接。   第一步:注册,并注册connect事件。 ...
  • z69183787
  • z69183787
  • 2014-04-14 11:22
  • 937

NIO应用实现多客户端与服务端通信

服务端程序:package com.bh.server; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; ...
  • cuiyaoqiang
  • cuiyaoqiang
  • 2016-05-10 10:25
  • 1100

Java实现服务器和客户端简单通信

Java中网络编程这一块有封装的类库,使用简单,了解原理可以教容易实现服务器和客户端的简单通信。在编程之前,首先要需要对TCP/IP协议有一定的了解,需要知道Socket套接字的作用以及用法,这个可以在API文档中去查看。两通讯实体之间通信需要掌握数据的传输方式,这里主要掌握java中IO流的使用。...
  • superxiaolong123
  • superxiaolong123
  • 2017-04-13 21:40
  • 1379

Java 利用 Socket 实现服务器客户端聊天

Socket是网络编程中最基本的通信接口,常用的网络辅助类,比如URL等之类,其底层还是基于Socket来实现的。 而Socket,形象来说,就是连接通信的两端,比如这样 S<==>S,中间的通道就是网络了,而简单地利用Socket,我们就可以来实现一个简单的聊天功能。 1. Serve...
  • foolsheep
  • foolsheep
  • 2014-05-15 00:03
  • 3458

JAVA NIO 服务器与客户端实现示例(代码1)

公共类: [java] view plain copy print? package com.stevex.app.nio;     import java.nio.ByteBuffer;...
  • zmx729618
  • zmx729618
  • 2017-01-17 16:47
  • 1631

Java nio 客户端连接Server

在做通信系统的开发过程中,经常需要使用Socket通信。java新的io机制给我提供了一个很好的异步socket通信方式,这段时间用java写了一个客户端用来连接server。发现运行效率还比较让人满意。下面是我实现的部分功能。 连接服务器的socket,多线程启动。如果连接失败就重连。 ...
  • z69183787
  • z69183787
  • 2016-10-27 14:37
  • 526

Java NIO实现多个客户端之间的消息互发,客户端与服务器完整代码

  • 2017-06-15 09:33
  • 649KB
  • 下载

JAVA NIO 服务器与客户端实现示例

以下代码只兼容Java 7及以上版本,对于一些关键地方请看注释说明。 公共类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package
  • z69183787
  • z69183787
  • 2016-10-27 14:41
  • 894