1. 程式人生 > >java socket和netty通訊

java socket和netty通訊

一、Socket簡單通訊

1、先啟動server端

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**  
* @Title: tcpServer.java   
* @Description: TODO  
* @author pcm  
* @date 2018年6月8日 下午3:31:51
* @version V1.0  
*/
public class TcpServer {
	public static void main(String[] args) throws IOException {
		System.out.println("tcp協議伺服器端啟動");
		ServerSocket serverSocket = new ServerSocket(8080);
		//接收客戶端請求
		Socket accept = serverSocket.accept();
		InputStream inputStream = accept.getInputStream();
		//將位元組流轉換成String型別
		byte[] bytes =new byte[1024];
		int len =inputStream.read(bytes);
		String result =new String(bytes, 0,len);
		System.out.println("伺服器端接收客戶端內容:"+result);
		serverSocket.close();
	}

}
2、啟動客戶端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**  
* @Title: tcpServer.java   
* @Description: TODO  
* @author pcm  
* @date 2018年6月8日 下午3:31:51
* @version V1.0  
*/
public class TcpClient {
	public static void main(String[] args) throws IOException {
		System.out.println("tcp協議客戶端啟動");

		// 建立socket客戶端
		Socket socket = new Socket("127.0.0.1", 8080);
		OutputStream outputStream = socket.getOutputStream();
		outputStream.write("我是客戶端".getBytes());
		socket.close();
	}

}

使用執行緒池支援訪問

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**  
* @Title: tcpServer.java   
* @Description: TODO  
* @author pcm  
* @date 2018年6月8日 下午3:31:51
* @version V1.0  
*/
public class TcpServer {
	public static void main(String[] args) throws IOException {
		System.out.println("tcp協議伺服器端啟動");
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		// 建立服務端介面
		ServerSocket serverSocket = new ServerSocket(8080);
		try {
			while (true) {
				// 接收客戶端請求
				final Socket accept = serverSocket.accept();
				newCachedThreadPool.execute(new Runnable() {
					public void run() {
						try {
							InputStream inputStream = accept.getInputStream();
							// 將位元組流轉換成String型別
							byte[] bytes = new byte[1024];
							int len = inputStream.read(bytes);
							String result = new String(bytes, 0, len);
							System.out.println("伺服器端接收客戶端內容:" + result);
							OutputStream outputStream = accept.getOutputStream();
							outputStream.write("服務端接收到請求了".getBytes());
						} catch (IOException e) {
							// TODO Auto-generated catch block
						}
					}
				});

			}
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			serverSocket.close();
		}
	}
}

二、使用netty3通訊

1.netty3服務端

/**  
* @Title: NettyServer.java   
* @Description: TODO  
* @author pcm  
* @date 2018年6月11日 下午3:27:24
* @version V1.0  
*/
// Netty 伺服器端
public class NettyServer {
	public static void main(String[] args) {
		// 1.建立服務物件
		ServerBootstrap serverBootstrap = new ServerBootstrap();
		// 2.建立兩個執行緒池 第一個監聽埠號 nio監聽
		ExecutorService boss = Executors.newCachedThreadPool();
		ExecutorService work = Executors.newCachedThreadPool();
		// 3.將執行緒池放入工程
		serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss, work));
		// 4.設定管道工程
		serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			// 設定管道
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				ChannelPipeline pipeline = Channels.pipeline();
				// 傳輸資料的時候直接為string型別
				pipeline.addLast("decoder", new StringDecoder());
				pipeline.addLast("encoder", new StringDecoder());
				// 設定事件監聽類
				pipeline.addLast("serverHandler", new ServerHandler());
				return pipeline;
			}
		});
		// 繫結埠號
		serverBootstrap.bind(new InetSocketAddress(8080));
		System.out.println("伺服器端已經啟動");
	}
}

class ServerHandler extends SimpleChannelHandler {

	// 通道被關閉的時候就會觸發
	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.channelClosed(ctx, e);
		System.out.println("channelClosed");
	}

	// 必須要建立連線,關閉通道時候才會觸發
	@Override
	public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.channelDisconnected(ctx, e);
		System.out.println("channelDisconnected");
	}

	// 接收出現異常
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(ctx, e);
		e.getCause().printStackTrace();
		System.out.println("exceptionCaught:");
	}

	// 接收客戶端資料
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.messageReceived(ctx, e);
		System.out.println("messageReceived");
		System.out.println("伺服器端獲取客戶端發來的引數" + e.getMessage());
		String msg = "Did you say '" + e.getMessage() + "'?\n";
		ChannelBuffer buffer = ChannelBuffers.buffer(msg.length());
		buffer.writeBytes(msg.getBytes());
		e.getChannel().write(buffer);
	}
}

2.netty3客戶端

public class NettyClient {
	public static void main(String[] args) {
		// 1.建立服務物件
		ClientBootstrap clientBootstrap = new ClientBootstrap();
		// 2.建立兩個執行緒池 第一個監聽埠號 nio監聽
		ExecutorService boss = Executors.newCachedThreadPool();
		ExecutorService work = Executors.newCachedThreadPool();
		// 3.將執行緒池放入工程
		clientBootstrap.setFactory(new NioClientSocketChannelFactory(boss, work));
		// 4.設定管道工程
		clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			// 設定管道
			@Override
			public ChannelPipeline getPipeline() throws Exception {
				ChannelPipeline pipeline = Channels.pipeline();
				// 傳輸資料的時候直接為string型別
				pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
				pipeline.addLast("encoder", new StringDecoder(CharsetUtil.UTF_8));
				// 設定事件監聽類
				pipeline.addLast("clientHandler", new ClientHandler());
				return pipeline;
			}
		});
		// 繫結埠號
		ChannelFuture connect = clientBootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
		Channel channel = connect.getChannel();
		System.out.println("服務端啟動");
		Scanner scanner = new Scanner(System.in);
		while (true) {
			System.out.println("請輸入內容");
			String msg= scanner.next();
			 ChannelBuffer buffer = ChannelBuffers.buffer(msg.length());
			 buffer.writeBytes(msg.getBytes());
			 channel.write(buffer);
		}

	}
}

class ClientHandler extends SimpleChannelHandler {

	// 通道被關閉的時候就會觸發
	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.channelClosed(ctx, e);
		System.out.println("channelClosed");
	}

	// 必須要建立連線,關閉通道時候才會觸發
	@Override
	public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.channelDisconnected(ctx, e);
		System.out.println("channelDisconnected");
	}

	// 接收出現異常
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(ctx, e);
		System.out.println("exceptionCaught");
	}

	// 接收客戶端資料
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		// TODO Auto-generated method stub
		super.messageReceived(ctx, e);
		System.out.println("messageReceived");
		System.out.println("伺服器端向客戶端法律司的引數" + e.getMessage());

	}
}

三、使用netty5通訊

1.netty5服務端

public class NettyServer {

	public static void main(String[] args) {
		System.out.println("伺服器端啟動....");
		try {
			// 1.建立兩個執行緒池,一個負責接收客戶端,一個進行傳輸
			NioEventLoopGroup pGroup = new NioEventLoopGroup();
			NioEventLoopGroup cGroup = new NioEventLoopGroup();
			// 2.建立輔助類
			ServerBootstrap b = new ServerBootstrap();
			b.group(pGroup, cGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024)
					// 3.設定緩衝區與傳送區大小
					.option(ChannelOption.SO_SNDBUF, 32 * 1024).option(ChannelOption.SO_RCVBUF, 32 * 1024)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						protected void initChannel(SocketChannel sc) throws Exception {
							//設定返回型別為String型別
							sc.pipeline().addLast(new StringDecoder());
							sc.pipeline().addLast(new ServerHandler());
						}
					});

			ChannelFuture cf = b.bind(8080).sync();
			cf.channel().closeFuture().sync();
			pGroup.shutdownGracefully();
			cGroup.shutdownGracefully();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
class ServerHandler extends ChannelHandlerAdapter{
	/** 
	 當通道被呼叫,執行方法(拿到資料)
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		super.channelRead(ctx, msg);
		String value = (String) msg;
		System.out.println("伺服器端收到客戶端msg:"+value);
		//回覆客戶端
		ctx.writeAndFlush("收到msg"+value);
	}
}

2、netty客戶端

/**  
* @Package Netty5 
* @Title: NettyServer.java   
* @Description: TODO  
* @author pcm  
* @date 2018年6月12日 上午10:52:55
* @version V1.0  
*/
public class NettyClient {

	public static void main(String[] args) {
		System.out.println("客戶端啟動....");
		try {
			// 建立負責接收客戶端連線
			NioEventLoopGroup pGroup = new NioEventLoopGroup();
			Bootstrap b = new Bootstrap();
			b.group(pGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
				@Override
				protected void initChannel(SocketChannel sc) throws Exception {
					// 設定返回型別為String型別
					sc.pipeline().addLast(new StringDecoder());
					sc.pipeline().addLast(new ClientHandler());
				}
			});
            
			ChannelFuture cf = b.connect("127.0.0.1",8080).sync();
			cf.channel().writeAndFlush(Unpooled.wrappedBuffer("123".getBytes()));
			cf.channel().writeAndFlush(Unpooled.wrappedBuffer("我是客戶端".getBytes()));
			cf.channel().closeFuture().sync();
			pGroup.shutdownGracefully();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

class ClientHandler extends ChannelHandlerAdapter {
	/** 
	 當通道被呼叫,執行方法
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		super.channelRead(ctx, msg);
		// 接收資料
		String value = (String) msg;
		System.out.println("client msg" + value);
	}
}