1.BIO
客户端简单编写
public static void main(String[] args) { try { //1.创建socket对象 Socket socket=new Socket("127.0.0.1", 9999); //2.从socket 获取字节输入流 OutputStream out=socket.getOutputStream(); //字节输入流换成打印流 PrintStream ps=new PrintStream(out,true); Scanner san=new Scanner(System.in); while (true){ System.out.print("请说:"); ps.println(san.nextLine()) ; } } catch (IOException e) { e.printStackTrace(); } }
服务端简单编写
public static void main(String[] args) { try { System.out.println("开始注册端口"); //注册端口 ServerSocket serversocket=new ServerSocket(9999); //循环获取socket 监听 while(true){ Socket so=serversocket.accept(); new ServerThread(so).start(); } } catch (Exception e) { e.printStackTrace(); } }
定义一个ServerThread线程类
public class ServerThread extends Thread{ private Socket socket; public ServerThread(Socket so) { this.socket=so; } @Override public void run() { try { InputStream input=socket.getInputStream(); BufferedReader read=new BufferedReader(new InputStreamReader(input)); String msg; while( (msg=read.readLine())!=null ){ System.out.println(msg); } } catch (Exception e) { e.printStackTrace(); } } }
2. NIO 代码开发,同样也是实现客户端和服务端交互
客户端:
public class Client { //1.选择器 private Selector selector; //2.客户端通道 private SocketChannel socketChannel; //3.端口 private static int PORT = 9998; //4.IP private static String IP="127.0.0.1"; //5.实例化 public Client(){ try { //6.开启选择器 selector=Selector.open(); //7.开启通道 socketChannel=SocketChannel.open(new InetSocketAddress(IP,PORT)); //8.设置非阻塞 socketChannel.configureBlocking(false); //9.绑定端口IP // socketChannel.bind(new InetSocketAddress(IP,PORT)); //10 监听读事件 socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("客户端准备好了"); } catch (IOException e) { System.out.println("客户端连接失败"); e.printStackTrace(); } } public static void main(String[] args) { Client client=new Client(); System.out.println("转发线程启动"); new Thread(() -> { System.out.println("开始转发"); client.readInfo(); }).start(); Scanner sc=new Scanner(System.in); while (sc.hasNext()){ String msg= sc.nextLine(); client.writrToServer(msg); System.out.println("-------------"); } } private void writrToServer(String msg) { try { socketChannel.write(ByteBuffer.wrap(msg.getBytes())); } catch (IOException e) { e.printStackTrace(); } } private void readInfo() { try { while(selector.select()>0) { Iterator<SelectionKey> it =selector.selectedKeys().iterator(); while(it.hasNext()){ //取数 SelectionKey sk=it.next(); if(sk.isReadable()){ SocketChannel sc= (SocketChannel) sk.channel(); ByteBuffer bf=ByteBuffer.allocate(1024); sc.read(bf); bf.flip(); System.out.println(new String(bf.array(),0,bf.remaining())); System.out.println("----转发结束---------"); } it.remove(); } } } catch (IOException e) { e.printStackTrace(); } } }
服务端:
public class Server { //1. private ServerSocketChannel sschannel; //2. private Selector selector; //3.定义端口 private final int PORT=9998; //构造器 public Server(){ try { //开启选择器,初始化选择器 selector=Selector.open(); //开启通道 sschannel=ServerSocketChannel.open(); //设置非阻塞 sschannel.configureBlocking(false); //设置连接 sschannel.bind(new InetSocketAddress(PORT)); //注册连接事件 sschannel.register(selector, SelectionKey.OP_ACCEPT); } catch (IOException e) { e.printStackTrace(); } } public void connect() { try { System.out.println("服务端准备就绪"); //有连接的事件就一直循环等待 while (selector.select()>0){ //迭代所有事件 Iterator<SelectionKey> it=selector.selectedKeys().iterator(); while (it.hasNext()){ //获取当前事件 SelectionKey sk= it.next(); //判断事件状态 if(sk.isAcceptable()){ //11.获取当前接入客户端通道 SocketChannel sc= sschannel.accept(); //设置事件通道阻塞 sc.configureBlocking(false); //13.本客户端注册读事件到选择器 sc.register(selector,SelectionKey.OP_READ); }else if(sk.isReadable()){ clientGetData(sk); } it.remove(); } } }catch (Exception e){ } } private void clientGetData(SelectionKey sk) { //获取当前事件通道 SocketChannel socketChannel= null; //分配空间 ByteBuffer bf=ByteBuffer.allocate(1024); try { socketChannel= (SocketChannel) sk.channel(); int leg=socketChannel.read(bf); if(leg>0){ bf.flip(); String msg=new String(bf.array(),0,bf.remaining()); System.out.println("客户端接收消息:"+msg); sendMsgAllclient(msg,socketChannel); } } catch (IOException e) { System.out.println("有人离线了"); try { sk.cancel(); socketChannel.close(); } catch (IOException ioException) { ioException.printStackTrace(); } e.printStackTrace(); } } private void sendMsgAllclient(String msg, SocketChannel socketChannel) { System.out.println("服务端开始转发这个消息,当前线程:"+Thread.currentThread().getName()); for(SelectionKey skey : selector.keys()){ Channel channel= skey.channel(); if(channel instanceof SocketChannel && channel!=socketChannel){ ByteBuffer buffer=ByteBuffer.wrap(msg.getBytes()); try { ((SocketChannel) channel).write(buffer); } catch (IOException e) { System.out.println("为啥没有收到"); e.printStackTrace(); } } } } public static void main(String[] args) { Server server=new Server(); server.connect(); } }