SocketChannel实例

package com.test.socket;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
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;

public class SocketChannelTestMain {
	private static final int port = 30008;
	private static final int TIMEOUT = 3000;
	private static byte end = '\n';
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Thread serverThread = new ServerThread();
		serverThread.start();
		Thread clientThread = new ClientThread();
		clientThread.start();
		Thread.sleep(2000);
	}

	static class ServerThread extends Thread {

		@Override
		public void run() {
			ServerSocketChannel channel = null;
			try {
				channel = ServerSocketChannel.open();
				SocketAddress address = new InetSocketAddress(port);
				channel.configureBlocking(false);
				ServerSocket socket = channel.socket();
				socket.setReuseAddress(true);
				socket.bind(address);
				Selector selector = Selector.open();
				channel.register(selector, SelectionKey.OP_ACCEPT);
				while (selector.isOpen()) {
					if (selector.select(TIMEOUT) == 0) {
						System.out.print("...");
						continue;
					}
					Iterator<SelectionKey> it = selector.selectedKeys()
							.iterator();
					while (it.hasNext()) {
						SelectionKey key = it.next();
						if (!key.isValid()) {
							key.channel().close();
							continue;
						}
						if (key.isAcceptable()) {
							this.accept(key);
						} else if (key.isReadable()) {
							this.read(key);
						} else if (key.isWritable()) {
							this.write(key);
						}
						it.remove();
					}
					
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(channel != null){
					try{
						channel.close();
					}catch(Exception ex){
						ex.printStackTrace();
					}
				}
			}
		}

		private void accept(SelectionKey key) throws Exception {
			SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
			socketChannel.configureBlocking(false);
			socketChannel.register(key.selector(), SelectionKey.OP_READ);
			// 获取连接后,开始准备接受client的write,即当前socket的read.
			System.out.println("Server accept...");
		}

		private void read(SelectionKey key) throws Exception {
			System.out.println("Server reads begin..");
			SocketChannel socketChannel = (SocketChannel) key.channel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			while (socketChannel.read(buffer) != -1) {
				byte last = buffer.get(buffer.position()-1);
				System.out.println("l:" + buffer.position() + "//" + last + "//" + end);
				if(last == end){
					break;
				}
				Thread.sleep(500);
			}
			buffer.flip();
			Charset charset = Charset.defaultCharset();
			CharBuffer charBuffer = charset.decode(buffer);
			System.out.println("Server read:" + charBuffer.toString());
			key.interestOps(SelectionKey.OP_WRITE);
		}

		private void write(SelectionKey key) throws Exception {
			SocketChannel socketChannel = (SocketChannel) key.channel();
			Charset charset = Charset.defaultCharset();
			String data = "S : " + System.currentTimeMillis();
			ByteBuffer byteBuffer = charset.encode(data);
			int limit = byteBuffer.limit();
			byteBuffer.clear();
			byteBuffer.position(limit);
			byteBuffer.put(end);
			byteBuffer.flip();
			while(byteBuffer.hasRemaining()){
				socketChannel.write(byteBuffer);
			}
			key.interestOps(SelectionKey.OP_READ);
		}
	}

	static class ClientThread extends Thread {
		@Override
		public void run() {
			SocketChannel channel = null;
			try {
				channel = SocketChannel.open();
				channel.configureBlocking(false);
				boolean isSuccess = channel.connect(new InetSocketAddress(port));
				if(!isSuccess){
					while (!channel.finishConnect()) {
						System.out.println("Connecting...");
						Thread.sleep(1000);
					}
				}
				Selector selector = Selector.open();
				channel.register(selector, SelectionKey.OP_WRITE);
				while (selector.isOpen()) {
					if (selector.select(TIMEOUT) == 0) {
						System.out.println("C...");
						continue;
					}
					Iterator<SelectionKey> it = selector.selectedKeys()
							.iterator();
					while (it.hasNext()) {
						SelectionKey key = it.next();
						if (!key.isValid()) {
							channel.close();
							return;
						}
						if (key.isWritable()) {
							write(key);
						} else if (key.isReadable()) {
							read(key);
						}
						it.remove();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				if(channel != null){
					try{
						channel.close();
					}catch(Exception ex){
						ex.printStackTrace();
					}
				}
			}
		}

		private void write(SelectionKey key) throws Exception {
			SocketChannel socketChannel = (SocketChannel) key.channel();
			Charset charset = Charset.defaultCharset();
			String data = "C : " + System.currentTimeMillis();
			ByteBuffer byteBuffer = charset.encode(data);
			int limit = byteBuffer.limit();
			byteBuffer.clear();
			byteBuffer.position(limit);
			byteBuffer.put(end);
			byteBuffer.flip();
			while(byteBuffer.hasRemaining()){
				socketChannel.write(byteBuffer);
			}
			System.out.println("Client has writeen!");
			key.interestOps(SelectionKey.OP_READ);
		}

		private void read(SelectionKey key) throws Exception {
			SocketChannel socketChannel = (SocketChannel) key.channel();
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			while(socketChannel.read(byteBuffer) != -1){
				byte last = byteBuffer.get(byteBuffer.position()-1);
				if(last == end){
					break;
				}
			}
			byteBuffer.flip();
			Charset charset = Charset.defaultCharset();
			CharBuffer charBuffer = charset.decode(byteBuffer);
			System.out.println("Client read: " + charBuffer.toString());
			key.interestOps(SelectionKey.OP_WRITE);
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值