百知教育 - 孙帅 - 18_网络编程
01_网络基础
-
网络:
- 若干主机(host) 形成的有机整体;
- 按提供的服务不同,可以分为客户端、服务器
-
IP地址
- 标识网络主机的逻辑地址(192.168.0.1 四分十进制)
-
端口号
- 用来标识主机中的进程。
- 进程会预先绑定唯一的端口号,用来对外部 监听。
- 端口号范围:0-65535,其中0-1024为 预留端口。
-
四层协议
- 应用层 HTTP FTP SMTP TELNET
- 传输层 TCP(传输控制协议): 面向连接、安全可靠 UDP(用户数据报协议):无连接、不可靠
- 网络层 IP协议:约定了网络如何 寻址 和 路由
- 网络接口
02_基于BIO的网络编程
-
BioServer代码:
package day24; import java.net.*; import java.io.*; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; public class TestBioServer{ public static void main(String[] args){ ServerSocket ss = null; try{ ss = new ServerSocket(9000); //绑定9000端口 }catch(IOException e){ e.printStackTrace(); } Socket s = null; ExecutorService es = Executors.newFixedThreadPool(30); while(true){ try{ s = ss.accept(); //监听 }catch(IOException e){ e.printStackTrace(); } es.submit(new Task(s)); } } } class Task implements Runnable{ Socket s; public Task(Socket s){ this.s = s; } public void run(){ InputStream is = null; OutputStream os = null; PrintWriter pw = null; InputStreamReader isr= null; BufferedReader br = null; try{ System.out.println(s.getInetAddress()); is = s.getInputStream(); os = s.getOutputStream(); pw = new PrintWriter(os); isr = new InputStreamReader(is); br = new BufferedReader(isr); for(int i = 1 ; i <= 30 ; i++){ String s1 = br.readLine(); String s2 = s1.toUpperCase(); pw.println(s2); } }catch(IOException e){ e.printStackTrace(); }finally{ if(s != null){ try{ s.close(); }catch(IOException e){ e.printStackTrace(); } } } } }
-
BioClient代码:
package day24; import java.net.*; import java.io.*; public class TestBioClient{ public static void main(String[] args){ Socket s = null; InputStream is = null; OutputStream os = null; PrintWriter pw = null; InputStreamReader isr= null; BufferedReader br = null; try{ s = new Socket("127.0.0.1" , 9000); //监听 is = s.getInputStream(); os = s.getOutputStream(); pw = new PrintWriter(os); isr = new InputStreamReader(is); br = new BufferedReader(isr); for(int i = 1 ; i <= 30 ; i++){ pw.println("hello "+i); pw.flush(); String s1 = br.readLine(); System.out.println(s1); Thread.sleep(200); } }catch(Exception e){ e.printStackTrace(); }finally{ if(s != null){ try{ s.close(); }catch(IOException e){ e.printStackTrace(); } } } } }
03_基于NIO的服务器编程
-
代码(编译通过):
package day24; import java.util.Set; import java.util.Iterator; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.channels.ServerSocketChannel; import java.net.InetSocketAddress; public class TestNioServer{ public static void main(String[] args) throws Exception{ ServerSocketChannel schannel = ServerSocketChannel.open(); schannel.bind(new InetSocketAddress(9000)); //绑定9000端口 schannel.configureBlocking(false); //设置非阻塞 Selector selector = Selector.open(); //开启选择器 schannel.register(selector , SelectionKey.OP_ACCEPT); //注册感兴趣的事件:有客户端连 while(true){ selector.select(); //阻塞 Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); it.remove(); if(key.isAcceptable()){ //当有客户端连接时的处理 SocketChannel channel = schannel.accept(); channel.configureBlocking(false); channel.register(selector , SelectionKey.OP_READ); //感兴趣时间:准备好读取数据 } if(key.isReadable()){ //当有客户端发送数据时,服务器准备去读数据 ByteBuffer buffer = ByteBuffer.allocate(20); SocketChannel channel = (SocketChannel)key.channel(); channel.read(buffer); buffer.flip(); //ByteBuffer --> String String str = Charset.defaultCharset().defaultCharset().decode(buffer).toString(); str = str.toUpperCase(); buffer = ByteBuffer.wrap(str.getBytes()); //str --> ByteBuffer channel.write(buffer); } } } } }
04_基于NIO的客户端编程
-
代码(编译通过):
package day24; import java.util.Set; import java.io.IOException; import java.nio.charset.Charset; import java.util.Iterator; import java.nio.ByteBuffer; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; public class TestNioClient{ public static void main(String[] args) throws Exception{ SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); Selector selector = Selector.open(); channel.register(selector , SelectionKey.OP_CONNECT); channel.connect(new InetSocketAddress("192.168.0.16" , 9000)); //向服务器写三十个hello Thread t = new Thread(){ public void run(){ try{ while(! channel.isConnected()){} for(int i = 1 ; i <= 30 ; i++){ String str = "hello"+i; ByteBuffer buffer = ByteBuffer.wrap(str.getBytes()); channel.write(buffer); Thread.sleep(200); } } finally{ try{ channel.close(); selector.close(); } catch(Exception e){ e.printStackTrace(); } } } }; t.start(); while(true){ selector.select(); if(! selector.isOpen()) break; Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); it.remove(); if(key.isConnectable()){ if(! channel.isConnected()) channel.finishConnect(); //如果连接还没完成,则完成连接 channel.register(selector , SelectionKey.OP_READ); } if(key.isReadable()){ ByteBuffer buffer = ByteBuffer.allocate(20); channel.read(buffer); buffer.flip(); String str = Charset.defaultCharset().decode(buffer).toString(); System.out.println(str); } } } } }
05_基于NIO的网络编程_优雅的退出
-
服务器代码(编译通过):
package day24; import java.util.Set; import java.util.Iterator; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.channels.ServerSocketChannel; import java.net.InetSocketAddress; public class TestNioServer{ public static void main(String[] args) throws Exception{ ServerSocketChannel schannel = ServerSocketChannel.open(); schannel.bind(new InetSocketAddress(9000)); //绑定9000端口 schannel.configureBlocking(false); //设置非阻塞 Selector selector = Selector.open(); //开启选择器 schannel.register(selector , SelectionKey.OP_ACCEPT); //注册感兴趣的事件:有客户端连 while(true){ selector.select(); //阻塞 Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); it.remove(); if(key.isAcceptable()){ //当有客户端连接时的处理 SocketChannel channel = schannel.accept(); channel.configureBlocking(false); channel.register(selector , SelectionKey.OP_READ); //感兴趣时间:准备好读取数据 } if(key.isReadable()){ //当有客户端发送数据时,服务器准备去读数据 ByteBuffer buffer = ByteBuffer.allocate(20); SocketChannel channel = (SocketChannel)key.channel(); channel.read(buffer); buffer.flip(); //ByteBuffer --> String String str = Charset.defaultCharset().defaultCharset().decode(buffer).toString(); if("quit".equals(str)){ channel.write(ByteBuffer.wrap("quit".getBytes())); channel.close(); } else{ str = str.toUpperCase(); buffer = ByteBuffer.wrap(str.getBytes()); //str --> ByteBuffer channel.write(buffer); } } } } } }
-
客户端代码(编译通过):
package day24; import java.util.Set; import java.io.IOException; import java.nio.charset.Charset; import java.util.Iterator; import java.nio.ByteBuffer; import java.net.InetSocketAddress; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; public class TestNioClient{ public static void main(String[] args) throws Exception{ SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); Selector selector = Selector.open(); channel.register(selector , SelectionKey.OP_CONNECT); channel.connect(new InetSocketAddress("192.168.0.16" , 9000)); //向服务器写三十个hello Thread t = new Thread(){ public void run(){ try{ while(! channel.isConnected()){} for(int i = 1 ; i <= 30 ; i++){ String str = "hello"+i; ByteBuffer buffer = ByteBuffer.wrap(str.getBytes()); channel.write(buffer); Thread.sleep(200); } ByteBuffer buffer = ByteBuffer.wrap("quit".getBytes()); channel.write(buffer); } catch(Exception e){ e.printStackTrace(); } } }; t.start(); while(true){ selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()){ SelectionKey key = it.next(); it.remove(); if(key.isConnectable()){ if(! channel.isConnected()) channel.finishConnect(); //如果连接还没完成,则完成连接 channel.register(selector , SelectionKey.OP_READ); } if(key.isReadable()){ ByteBuffer buffer = ByteBuffer.allocate(20); channel.read(buffer); buffer.flip(); String str = Charset.defaultCharset().decode(buffer).toString(); if("quit".equals(str)){ channel.close(); selector.close(); return; } else System.out.println(str); } } } } }
06_基于AIO的网络编程
-
服务器代码(编译通过):
package day25; import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.ByteBuffer; import java.net.InetSocketAddress; import java.util.concurrent.Future; import java.nio.channels.CompletionHandler; import java.nio.channels.AsynchronousSocketChannel; public class TestAIOServer{ public static void main(String[] args) throws Exception{ AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(); server.bind(new InetSocketAddress(8989)); //Future<AsynchronousServerSocketChannel> f = server.accept(); //AsynchronousSocketChannel channel = f.get(); server.accept(null , new CompletionHandler<AsynchronousSocketChannel , Object>(){ @Override public void completed(AsynchronousSocketChannel channel , Object attachment){ try{ System.out.println("连接成功"); ByteBuffer buffer = ByteBuffer.wrap("hello".getBytes()); Future<Integer> f = channel.write(buffer); f.get(); channel.close(); }catch(Exception e){ e.printStackTrace(); } } @Override public void failed(Throwable exc , Object attachment){} }); System.out.println("main go on"); while(true){ Thread.sleep(1000); } } }
-
客户端代码(编译通过):
package day25; import java.nio.channels.AsynchronousSocketChannel; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.net.InetSocketAddress; import java.nio.channels.CompletionHandler; import java.nio.charset.Charset; public class TestAIOClient{ public static void main(String[] args) throws Exception{ AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); client.connect(new InetSocketAddress("localhost" , 8989) , null , new CompletionHandler<Void , Object>(){ @Override public void completed(Void result , Object attachment){ try{ System.out.println("连接服务器成功"); ByteBuffer buffer = ByteBuffer.allocate(20); Future<Integer> f = client.read(buffer); f.get(); buffer.flip(); String str = Charset.defaultCharset().decode(buffer).toString(); System.out.println(str); client.close(); }catch(Exception e){ e.printStackTrace(); } } @Override public void failed(Throwable exc , Object attachment){} }); Thread.sleep(2000); } }