• B031-网络编程 Socket Http TomCat


    计算机网络

    见文档

    网络编程相关术语

    见文档

    IP地址
    ip的概念

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    一个局域网内不同计算机的网段是一样的,广域网IP也是一样的

    同一台计算机中可以存在多个不同类型IP,如本地局域网IP,无线局域网IP,广域网IP等
    在这里插入图片描述
    在运营商开户获得分配的ip

    找人要先找广域网IP,再找局域网IP,才能最后找到

    在局域网内部以局域网IP为身份,在外部广域网以广域网IP为身份。

    InerAdress的了解与测试
        @Test
        public void test4() throws Exception {
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println("localHost = " + localHost);		//localHost = LAPTOP-25C35TNG/192.168.1.115
            
            InetAddress name = InetAddress.getByName("LAPTOP-25C35TNG");
            System.out.println("name = " + name);				//name = LAPTOP-25C35TNG/192.168.1.115
            
            InetAddress baidu = InetAddress.getByName("baidu.com");
            System.out.println("baidu = " + baidu);				//baidu = baidu.com/39.156.66.10
            // 用ping也能拿到域名下的ip
            
            boolean reachable = baidu.isReachable(100);
            System.out.println("reachable = " + reachable);		//reachable = true
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    端口

    端口port用来区分不同的应用程序,端口号范围为065535,其中01023被系统所保留,如果自定义端口号,建议为1023以后的

    URL

    在这里插入图片描述

        @Test
        public void test5() throws Exception {
            //创建输入流
            URL url = new URL("https://www.baidu.com/");
            InputStream in = url.openStream();
            //获取输出流
            FileOutputStream out = new FileOutputStream("D:/test/baidu.html");
            //实现下载
    /*      byte[] b = new byte[1024];
            int i = 0;
            while ((i=in.read(b))!=-1){
                out.write(b,0,i);
            }                               */
            //用此IOUtils包可以替换以上代码
            IOUtils.copy(in,out);
            //释放资源
            out.close();
            in.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
        @Test
        public void test6() throws Exception {
            
            String encode = URLEncoder.encode("连衣裙", "utf-8");
            System.out.println("encode = " + encode);
    
            //%E8%BF%9E%E8%A1%A3%E8%A3%99
            String decode = URLDecoder.decode("%E8%BF%9E%E8%A1%A3%E8%A3%99", "utf-8");
            System.out.println("decode = " + decode);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    TCP、UDP和7层架构
    TCP

    1.TCP协议是Transmission Control Protocol传输控制协议,TCP是一种面向连接的、可靠的、基于字节流的传输层(Transport layer)通信协议。
    2.当客户和服务器彼此交互数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据,TCP 协议使用超时重传、数据确认等方式来确保数据包被正确地发送至目的端,故而效率低,速度慢;
    3.TCP可靠传输协议,不丢包,经常用来传输文件(回值内部处理),缺点是效率低,慢,而且占用资源,相当于打电话;

    UDP

    1.UDP(User Datagram Protocol)是一种无连接、不可靠、基于数据报的用户数据协议。
    2.UDP在传输数据报前不用在客户和服务器之间建立一个连接。它只是把数据报发送出去,但是并不能保证他们能到达目的,并且没有超时重发机制,故而传输速度很快;
    3.UDP不可靠传输协议,容易丢包。但是效率高,快,占用资源少。一般游戏中数据采用UDP传输数据,相当于发短信,快递;

    TCP与UDP的区别和联系

    1.首先它们都是传输层的协议;
    2.TCP 协议可靠,UDP 协议不可靠。可靠即指数据由A发送到B,是否能确保数据真的有送达到B;TCP 协议使用超时重传、数据确认等方式来确保数据包被正确地发送至目的端。而 UDP 协议无法保证数据从发送端正确传送到目的端,如果数据在传输过程中丢失或者目的端通过数据检验发现数据错误,则UDP协议只是简单地通知应用程序发送失败。对于 TCP 协议拥有的超时重传、数据确认等需要应用程序自己来处理这些逻辑;
    3.TCP 是面向连接的,UDP 是无连接的。这也比较好理解,因为 TCP 连接需要经历"三次握手";
    4.TCP 服务是基于流的,而UDP是基于数据报的,基于流的数据没有边界(长度)限制,而基于数据报的服务,每个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出;
    5.总之:TCP 协议为应用层提供可靠的、面向连接的、基于流的服务。而 UDP 协议则与 TCP 协议完全相反,它为应用层提供不可靠、无连接和基于数据报的服务;

    TCP的3次握手

    见文档,简单理解如下图
    在这里插入图片描述

    七层架构

    在这里插入图片描述
    物理层:光纤,网线
    数据链路层:网卡,网桥
    网络层:IP地址寻址,即IP协议
    传输层:TCP、UDP,数据按包来发送
    会话层:防止不断地IP寻址,
    表示层:解决不同系统之间的通信语法问题,如linux,windows
    应用层:定义了用于在网络中进行通信和传输数据的接口

    https://blog.csdn.net/weixin_39855693/article/details/89228286

    Socket编程

    服务端代码

    demo版代码

    public class Server {
    	public static void main(String[] args) throws Exception {
            // 初始化服务器
            System.out.println("初始化服务器");
            ServerSocket serverSocket = new ServerSocket(8089);
            System.out.println("服务器初始化成功");
    
            // 监听服务器
            Socket accept = serverSocket.accept();
            System.out.println("服务器连接成功");
            String hostName = accept.getInetAddress().getHostAddress();
            System.out.println("hostName = " + hostName);
    
            // 接收消息
            InputStream in = accept.getInputStream();
            // 转成字符流
            InputStreamReader inputStreamReader = new InputStreamReader(in,"UTF-8");
            // 放到缓冲流之后可以一行一行读数据
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String line = bufferedReader.readLine();
            System.out.println("客户端说 = " + line);               // line = GET /?name=hello HTTP/1.1
    
            // http://192.168.1.115:8088/?name=hello
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    优化版代码

    public class Server {
    	
    	ServerSocket serverSocket ;
    	
    	public Server() throws IOException{
    		System.out.println("初始化服务器");
    		serverSocket = new ServerSocket(8088);
    		System.out.println("服务器初始化成功.......");
    	}
    	
      	public static void main(String[] args) throws IOException {
    	 Server server = new Server();
    	 server.start();
      }
      
      	public void start() throws IOException{
    	  	// 监听服务器
    		System.out.println("服务启动成功等待连接");
    		Socket accept = serverSocket.accept();
    		System.out.println("服务器连接成功");
    		// 得到连接者名字
    		String hostName = accept.getInetAddress().getHostAddress();
    		System.out.println("连接服务器的名字是"+hostName);
    		
    		// 接收客户端的消息  
    		InputStream in = accept.getInputStream();
    		// 转为字符流
    		InputStreamReader inputStreamReader = new InputStreamReader(in,"UTF-8");
    		// 放到缓冲流之后可以一行一行读数据
    		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    		//读取一行
    		String readLine = bufferedReader.readLine();
    		System.out.println("客户端说:"+readLine);
      }
      
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    客户端代码
    public class Center {
    	Socket socket;
    	public Center() throws IOException{
    		System.out.println("初始化客户端...");
    		socket=new Socket("localhost", 8089);
    		System.out.println("已经连接上服务端");
    	}
    	
    	public static void main(String[] args) throws IOException {
    		Center center = new Center();
    		center.start();
    	}
     
    	public void start() throws IOException{
    	 	//向服务端发送消息
    		//客户端获取了一个输出流
    		OutputStream out = socket.getOutputStream();
    		//包装流
    		OutputStreamWriter os = new OutputStreamWriter(out, "UTF-8");//可以传输中文
    	    os.write("你好,服务器\n");
    		os.flush(); //刷新缓冲区,强制写出缓冲区的内容
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    http协议

    概念

    在这里插入图片描述
    不同的浏览器共同遵守的接收和发送数据的规范
    在这里插入图片描述
    网站可以根据请求头里的这些信息来决定返回哪种语言和格式版本的网页

    Http报文

    见文档

    Tomcat模拟

    底层用的socket编程,服务端接收客户端(浏览器)请求,返回html给客户端访问

    package cn.itsource.Test;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TomcatServer {
    	
    	private ServerSocket ss;
    	//构造器中初始化服务器的套接字
    	public TomcatServer() {
    		try {//初始化服务器,指定端口,访问时用该端口
    			ss = new ServerSocket(8091);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public void start() throws IOException{
    		//监听客户端的访问
    		Socket socket = ss.accept();
    		
    		//创建输出流
    		OutputStream os = socket.getOutputStream();
    		OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
    		PrintWriter pw = new PrintWriter(osw,true);
    		
    		//创建输入流:根据用户的访问找到服务器中的资源,用流的方式写出去
    		File file = new File("D:\\HBuilderProjects\\TestWebProject\\test.html");
    		InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
    		BufferedReader br = new BufferedReader(isr);
    		
    		//如何输出到页面呢?设置响应信息 -- 不然就只能输出到控制台或文本中,但是用户就需要在页面中看到内容,所以需要设置响应信息
    		pw.println("http1.1 200 OK");//1.设置响应头:协议版本 状态码 状态描述
    		pw.println("Content-Type: text/html;charset=UTF-8");//2.设置响应类型和字符编码
    //		pw.println("Content-Length: "+file.length());//可以不写
    		pw.println();//3.结束头部信息 -- 表示结束头部信息,接下来开始写内容
    		
    		//响应的内容
    		String len = null;
    		while((len=br.readLine())!=null){
    			pw.println(len);
    		}
    		
    //		pw.println("

    你好

    ");
    //关流 pw.close(); br.close(); } public static void main(String[] args) throws IOException { TomcatServer web = new TomcatServer(); while(true){ web.start(); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
  • 相关阅读:
    吉利发布新出行科技品牌“礼帽出行” 定位高品质定制化出行
    docker镜像详解
    测试开发人均年薪30w+?软件测试工程师如何进阶拿到高薪?
    低代码+BPM为一体构建的知识管理系统
    深度学习中端到端的概念
    英文字母pc是什么意思,互联网的pc指的是什么
    【算法训练-搜索算法 一】【DFS网格搜索框架】岛屿数量、岛屿的最大面积、岛屿的周长
    二叉树的前序、中序和后序非递归
    YOLOv1-v7全系列解析
    2、Redis中简单动态字符串的简介,也就是Redis中的键和值的字符串底层表达
  • 原文地址:https://blog.csdn.net/ffhgjgj6576567/article/details/134433159