发现日常学习过的知识不久就会遗忘,在此只是整理并记录一下学习笔记,做个回忆,并方便以后查阅,若有错误,欢迎指正
网络模型:TCP/IP网络模型是从OSI七层模型中演化来的,osi模型分为物理层,数据链路层,网络层,传输层,会话层,表示层,应用层,
TCP/IP网络模型分为:网络接口层,网际层,传输层,应用层
我对BIO的认识: 随着技术的发展,两个或以上的程序必然需要进行交互,于是BIO提供了一种端到端的通信,相当于对传输层的一种封装,对于开发人员而言
隐藏了传输的细节,将这些固定的“套路”抽象出来,提供一种端到端的通信,可以使我们更加专注于业务的开发,并且这种通讯是阻塞式的(block input output)
阻塞式:服务端启动,等待客户端的连接,在客户端连接到服务端后,服务端启动一个线程去监听客户端消息,客户端发送消息,并等待服务端返回(客户端一直阻塞),服务端收到消息,
将消息返回给客户端,此时一次交互完成。若还需交互,则不释放连接,客户端再次将消息发送给服务端,并等待返回,若不需要交互,则客户端释放连接。
生活中例子:A聘用了B干活,A让B去打印材料,在B去打印的期间,A一直在等待B的回来,在B没返回时,A将不做任何事情,一直等待B的返回,直到B返回后,A才接受到材料 (一次交互完成)
如果A还需要打印,则再次让B去打印,并等待B返回,期间什么都不干,如果不需要B去打印,就解除和B的聘用关系。直至再需要时聘用C
BIO代码实现(参考了一些市面上的视频资料,侵删)
服务端:
1 package com.study.server; 2 3 import com.study.info.HostInfo; 4 5 import java.io.IOException; 6 import java.io.PrintStream; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 import java.util.Scanner; 10 import java.util.concurrent.ExecutorService; 11 import java.util.concurrent.Executors; 12 13 public class BIOEchoServer { 14 public static void main(String[] args) throws Exception{ 15 ServerSocket socket = new ServerSocket(HostInfo.PORT); 16 System.out.println("服务端已经启动,监听端口为:" + HostInfo.PORT); 17 boolean flag = true; 18 ExecutorService executorService = Executors.newFixedThreadPool(10); 19 while (flag){ 20 Socket client = socket.accept(); 21 executorService.submit(new EchoClientHandler(client)); 22 } 23 executorService.shutdown(); 24 socket.close(); 25 } 26 27 private static class EchoClientHandler implements Runnable{ 28 29 private Socket client; 30 private Scanner scanner; 31 private PrintStream out; 32 private boolean flag = true; 33 34 public EchoClientHandler(Socket client){ 35 this.client = client; 36 try { 37 this.scanner = new Scanner(this.client.getInputStream()); 38 this.scanner.useDelimiter("\n"); 39 this.out = new PrintStream(this.client.getOutputStream()); 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 } 44 45 public void run() { 46 while (this.flag){ 47 if(this.scanner.hasNext()){ 48 String var = this.scanner.next().trim(); 49 System.out.println("收到客户端发来的"+var); 50 if("byebye".equals(var)){ 51 this.out.print("888888"); 52 this.flag = false; 53 } else { 54 out.println("【echo】" + var); 55 } 56 } 57 } 58 try { 59 this.scanner.close(); 60 this.out.close(); 61 this.client.close(); 62 } catch (IOException e) { 63 e.printStackTrace(); 64 } 65 } 66 } 67 }
客户端:
package com.study.client; import com.study.info.HostInfo; import com.study.util.InputUtil; import java.io.PrintStream; import java.net.Socket; import java.util.Scanner; public class BIOEchoClient { public static void main(String[] args) throws Exception{ Socket client = new Socket(HostInfo.HOST_NAME, HostInfo.PORT); Scanner scan = new Scanner(client.getInputStream()); scan.useDelimiter("\n"); PrintStream out = new PrintStream(client.getOutputStream()); boolean flag = true; while (flag){ String inputData = InputUtil.getString("请输入要发送的内容:").trim(); out.println(inputData); if (scan.hasNext()){ String str = scan.next(); System.out.println(str); } if ("byebye".equalsIgnoreCase(inputData)){ flag = false; } } client.close(); } }
工具包:
1 package com.study.util; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 7 public class InputUtil { 8 private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in)); 9 10 private InputUtil(){ 11 } 12 13 public static String getString(String prompt){ 14 boolean flag = true; //数据接受标记 15 String str = null; 16 while (flag){ 17 System.out.println(prompt); 18 try { 19 str = KEYBOARD_INPUT.readLine(); // 读取一行数据 20 if(str == null || "".equals(str)){ 21 System.out.println("数据输入错误,不允许为空!"); 22 }else { 23 flag = false; 24 } 25 } catch (IOException e) { 26 e.printStackTrace(); 27 } 28 } 29 return str; 30 } 31 }
IP及端口常量:
1 package com.study.info; 2 3 public class HostInfo { 4 public static final String HOST_NAME = "localhost"; 5 public static final int PORT = 9999; 6 }
效果

代码思路整理:
服务端:
1.通过ServerSocket创建监听,并创建线程池
2.当ServerSocket通过accept方法接受到请求时,线程池将会分出一个线程来执行所要进行的操作
3.(分出的线程会)等待客户端输入完成(即客户端安排做的事),客户端输入完成,则将会执行自己的处理并返回相应的结果(需要服务端来进行的运算,取数等一些操作,本例中是更改字符串)
4.服务端处理完成,则将数据返回客户端,等待客户端的下次输入事件,循环3,4,直至客户端释放连接
客户端:
通过Socket创建客户端,在接受到键盘输入后,将输入信息写入OutputStream流中,并等待客户端返回信息,
接受到返回信息后,则接着往下执行,若不需输入,则释放连接
