Java:实现Nio方式实现tcp通信

Posted 你是小KS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java:实现Nio方式实现tcp通信相关的知识,希望对你有一定的参考价值。

1. 声明

当前内容主要为复习使用Nio方式实现tcp通信,实现tcp之间的信号传递和解析

2. Server端

/**
 * 
 * @author hy
 * @createTime 2022-02-12 09:48:24
 * @description 当前内容为使用Nio方式操作socket进行通信操作
 *
 */
public class NioserverSocketTest 
	public static void main(String[] args) 
		int threadCount = 2;
		ServerSocketChannel serverSocketChannel = null;
		try 
			serverSocketChannel = ServerSocketChannel.open();
			serverSocketChannel.bind(new InetSocketAddress(8088));
			serverSocketChannel.configureBlocking(false);
			System.out.println("server wait connect....");
			ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(threadCount);
			final ServerSocketChannel channel = serverSocketChannel;
			// 使用线程方式处理连接
			AtomicInteger count = new AtomicInteger(0);

			//
			for (int i = 0; i < threadCount; i++) 
				NioChannelHandler handler = new NioChannelHandler();
				newFixedThreadPool.submit(new NioServerChannelAccepter(channel, handler, count));
			

			// 记录当前客户端数量
			while (true) 
				int i = count.get();
				System.out.println("当前客户端数量:" + i);
				try 
					Thread.sleep(1000L);
				 catch (InterruptedException e) 
					// TODO Auto-generated catch block
					e.printStackTrace();
				
			

		 catch (IOException e) 
			// TODO Auto-generated catch block
			e.printStackTrace();
			if (serverSocketChannel != null) 
				System.out.println("server shutdown now....");
				try 
					serverSocketChannel.close();
				 catch (IOException e2) 
					// TODO Auto-generated catch block
					e2.printStackTrace();
				
			
		
	

	private static class NioServerChannelAccepter implements Runnable 
		private final ServerSocketChannel channel;
		private final AtomicInteger clientCount;
		private final NioChannelHandler handler;

		public NioServerChannelAccepter(ServerSocketChannel channel, NioChannelHandler handler,
				AtomicInteger clientCount) 
			this.channel = channel;
			this.clientCount = clientCount;
			this.handler = handler;
		

		@Override
		public void run() 
			SocketChannel accept = null;
			while (true) 
				try 
					if (accept == null) 
						try 
							System.out.println(Thread.currentThread().getName() + ":wait to connect");
							Thread.sleep(2000L);
						 catch (InterruptedException e) 
							// TODO Auto-generated catch block
							e.printStackTrace();
						
						accept = channel.accept();
						if (accept != null) 
							clientCount.incrementAndGet();
						
					 else 
						handler.handler(accept);
					
				 catch (Exception e) 
					e.printStackTrace();
					if (accept != null) 
						clientCount.decrementAndGet();
						try 
							accept.close();
						 catch (IOException e2) 
							// TODO Auto-generated catch block
							e2.printStackTrace();
						
						accept = null;
					

				
			

		

	

	private static class NioChannelHandler 
		public void handler(SocketChannel accept) throws IOException 
			SocketAddress remoteAddress = accept.getRemoteAddress();
			System.out.println("server received a connected :" + remoteAddress);
			// 开始读取数据
			readBytes(accept);
			byte[] bytes = "你好客户端".getBytes();
			ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
			// ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
			// byteBuffer.put(bytes);
			int write = accept.write(byteBuffer);
			System.out.println("write bytes to client:" + write);
			byteBuffer.clear();
		
	

	private static void readBytes(SocketChannel accept) throws IOException 
		int bufferSize = 50;
		ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize);
		int len = accept.read(byteBuffer);
		while (true) 
			byte[] bytes = new byte[len];
			byteBuffer.flip();
			byteBuffer.get(bytes);
			System.out.println(bytes.length + ":read:" + Arrays.toString(bytes));
			byteBuffer.clear();
			if (len < bufferSize) 
				break;
			
			len = accept.read(byteBuffer);
		
	


启动一个服务器,并让2个线程处理连接

3. Client端

public class NioClientSocketTest 
	public static void main(String[] args) 
		SocketChannel socketChannel = null;
		try 
			socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 8088));
			socketChannel.write(ByteBuffer.wrap("你好世界!".getBytes("utf-8")));
			readBytes(socketChannel);
		 catch (IOException e) 
			// TODO Auto-generated catch block
			e.printStackTrace();
		finally 
			if(socketChannel!=null) 
				try 
					socketChannel.close();
				 catch (IOException e) 
					// TODO Auto-generated catch block
					e.printStackTrace();
				
			
		
	
	
	private static void readBytes(SocketChannel accept) throws IOException 
		int bufferSize = 50;
		ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize);
		int len = accept.read(byteBuffer);
		while (true) 
			byte[] bytes = new byte[len];
			byteBuffer.flip();
			byteBuffer.get(bytes);
			System.out.println(bytes.length + ":read:" + Arrays.toString(bytes));
			byteBuffer.clear();
			if (len < bufferSize) 
				break;
			
			len = accept.read(byteBuffer);
		
	


4. 测试

启动服务器

启动客户端

结果

测试成功

以上是关于Java:实现Nio方式实现tcp通信的主要内容,如果未能解决你的问题,请参考以下文章

NIO实现TCP的非阻塞通信

Netty介绍及应用

Java NIO实现非阻塞式socket通信

JAVA NIO 异步TCP服务端向客户端消息群发代码教程实战

JAVA NIO 异步TCP服务端向客户端消息群发代码教程实战

JAVA 远程 调用的几种实现方式简析 详细�0�3