网络编程

网络编程

1.1 概述

 

 

计算机网络:

计算机网络是指将 地理位置不同 的具有独立功能的 多台计算机及其外部设备,通过通信线路连接起来, 在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

 

网络编程的目的:

数据交换,通信

 

想要达到这个效果需要什么:

  1. 如何准确地定位网络上的一台主机 192.168.16.124:端口,定位i到这个计算机上的某个资源

  2. 找到了这个主机,如何传输数据呢?

 

Javaweb:网页编程 B/S架构

网络编程:TCP/IP C/S架构

1.2 网络通信的要素

如何实现网络的通信?

通信双方的地址:

  • ip

  • 端口号

  • 192.168.16.124(ip):5900(端口号:代表某一个应用)

规则:网络通信的协议

http,ftp,smtp,tcp,udp...

TCP/IP参考模型

 

 

小结:

  1. 网络编程中,有两个主要的问题

    • 如何准确地定位到网络上的一台或多台主机

    • 找到主机后如何进行通信

  2. 网络编程中的要素

    • IP和端口号 IP

    • 网络通信写协议 UDP,TCP

  3. 万物皆对象

 

1.3 IP

IP地址:InetAddress

  • 唯一定位一台网络上的的计算机

  • 127.0.0.1 : 本机 locallhost

  • ip地址的分类:

    • ipv4 / ipv6

      • IPV4:127.0.0.1 4个字节组成,0~255,42亿

      • IPV6:fe80::98a4:d381:b39:14c1%17 , 128位, 8个无符号整数

         2001:0bb2:aaaa:0015:0000:0000:laaa:1312

         

    • 公网(互联网) - 私网(局域网)

      • ABCD类地址

      • 192.168.xx.xx , 专门给组织内部使用的

  • 域名:记忆ip问题

1.4 端口

端口表示计算机上的一个程序的进程

  • 不同的进程由不同的端口号,不能冲突,用来区分软件

  • 端口被规定0~65535

  • TCP,UDP:65535*2 tcp:80,udp:80,单个协议下,端口号不能冲突

  • 端口分类

    • 公有端口:0~1023

      • HTTP:80

      • HTTPS:443

      • FTP:21

      • Telent:23

    • 程序注册端口:1024~49151,分配给用户或程序

      • Tomcat:8080

      • MySQL:3306

      • Oracle:1521

    • 动态、私有端口:49152~65535

       netstat -ano # 查看所有端口
       netstat -ano|findstr "5900" # 查看指定的端口
       tasklist|findstr "" # 查看指定端口的进程
       Crtl + Shift + Esc 任务管理器

       

 package com.kuang.lesson01;
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 
 public class TestInetSocketAddress {
     public static void main(String[] args) {
         InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 8080);
         System.out.println(inetSocketAddress);
         InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
         System.out.println(inetSocketAddress2);
 
         InetAddress address = inetSocketAddress.getAddress();
         System.out.println(address);
         System.out.println(inetSocketAddress.getHostName());//地址
         System.out.println(inetSocketAddress.getPort());//端口
    }
 }
 

1.5 通信协议

协议:约定,就好比我们现在说的是普通话交流。

网络通信协议:速率,传输码率,代码结构,传输控制。。。。

问题:非常复杂

大事化小:分层

TCP/IP协议簇:实际上是一组协议

重要:

  • TCP :用户传输协议

  • UDP :用户数据报协议

出名的协议:

  • TCP:

  • IP:网络互连协议

 

TCP UDP对比

TCP:打电话

  • 连接,稳定

  • 三次握手,四次挥手

     最少需要三次,才能稳定连接,以下是三次交流
     A:你瞅啥?
     B:瞅你咋地?
     A:干一场!
     
     
     A:我要断开了
     B:我知道你要断开了
     B:你真的断开了吗
     A:我真的要断开了

     

  • 客户端、服务端

  • 传输完成,释放连接,效率低

 

UDP:发短信

  • 不连接,不稳定

  • 客户端、服务端:没有明确的界限

  • 不管有没有准备好,都可以发给你

  • 导弹攻击

  • DDOS:洪水攻击~饱和攻击

1.6 TCP

客户端

  1. 连接服务器Socket

  2. 发送消息

 package com.kuang.lesson02;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 
 //客户端
 public class TcpClientDemo01 {
     public static void main(String[] args) throws IOException {
         //1. 要知道服务器的地址
         InetAddress serverIP = InetAddress.getByName("127.0.0.1");
         //2. 端口号
         int port = 9999;
         //3. 创建一个socket连接
         Socket socket = new Socket(serverIP,port);
 
         //4. 发送消息 IO流
         OutputStream os = socket.getOutputStream();
         os.write("你好,欢迎学习".getBytes(StandardCharsets.UTF_8));
 
         if(socket!=null)
             socket.close();
         if(os!=null)
             os.close();
    }
 }
 

 

服务器

  1. 建立服务的端口 ServerSocket

  2. 等待用户的的连接 accept

  3. 接受用户的消息

 package com.kuang.lesson02;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 
 //服务端
 public class TcpServerDemo01 {
     public static void main(String[] args) throws Exception {
         ServerSocket serverSocket = null;
         Socket socket = null;
         InputStream is = null;
         ByteArrayOutputStream baos = null;
 
         //1. 我得有一个地址
         serverSocket = new ServerSocket(9999);
         while(true){
             //2. 等待客户端连接过来
             socket = serverSocket.accept();
             //3. 读取客户端消息
             is = socket.getInputStream();
 
             //管道流
             baos = new ByteArrayOutputStream();
             byte[] buffer = new byte[1024];
             int len;
             while ((len=is.read(buffer))!=-1){
                 baos.write(buffer,0,len);
            }
             System.out.println(baos.toString());
        }
 
         //关闭资源
 //       if(baos!=null)
 //           baos.close();
 //       if(is!=null)
 //           is.close();
 //       if(socket!=null)
 //           socket.close();
 //       if(serverSocket!=null)
 //           serverSocket.close();
    }
 }
 

文件上传

客户端

 package com.kuang.lesson02;
 
 
 import java.io.*;
 import java.net.InetAddress;
 import java.net.Socket;
 
 public class TcpClientDemo02 {
     public static void main(String[] args) throws Exception {
         //1. 创建一个Socket连接
         Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
         //2. 创建一个输出流
         OutputStream os = socket.getOutputStream();
         //3. 读取文件
         FileInputStream fis = new FileInputStream(new File("D:\\Code\\JAVA\\网络编程\\src\\name.jpg"));
         //4. 写出文件
         byte[] buffer = new byte[1024];
         int len;
         while ((len = fis.read(buffer)) != -1){
             os.write(buffer,0,len);
        }
 
         //通知服务器我已经结束了
         socket.shutdownOutput();//我已经传输完了
 
 
         //确定服务器接收完毕,才能断开连接
         InputStream is = socket.getInputStream();
         //String byte[]
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
         byte[] buffer2 = new byte[1024];
         int len2;
         while ((len2 = fis.read(buffer2)) != -1){
             baos.write(buffer2,0,len2);
        }
         System.out.println(baos.toString());
 
         baos.close();
         is.close();
         fis.close();
         os.close();
         socket.close();
 
    }
 }
 

 

服务器端

 package com.kuang.lesson02;
 
 import java.io.*;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.nio.charset.StandardCharsets;
 
 public class TcpServerDemo02 {
     public static void main(String[] args) throws Exception {
         ServerSocket serverSocket = null;
         Socket socket = null;
         InputStream is = null;
 
         //1. 创建服务
         serverSocket = new ServerSocket(9000);
         //2. 等待客户端连接过来,阻塞式监听,会一直等待客户端连接
         socket = serverSocket.accept();
         //3. 获取输入流
         is = socket.getInputStream();
 
         //4. 文件输出
         FileOutputStream fos = new FileOutputStream(new File("D:\\Code\\JAVA\\网络编程\\src\\receive.jpg"));
         byte[] buffer = new byte[1024];
         int len;
         while ((len=is.read(buffer))!=-1){
             fos.write(buffer,0,len);
        }
 
         //通知客户端我接收完毕了
         OutputStream os = socket.getOutputStream();
         os.write("接收完毕".getBytes(StandardCharsets.UTF_8));
 
 
         //关闭资源
         fos.close();
         is.close();
         socket.close();
         serverSocket.close();
    }
 }

Tomcat

服务端

  • 自定义 S

  • Tomcat S:Java后台开发

客户端

  • 自定义 C

  • 浏览器 B

1.7 UDP

发短信:不用链接,需要知道对方的地址

发送端

 package com.kuang.lesson03;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.nio.charset.StandardCharsets;
 
 //不需要连接服务器
 public class UdpClientDemo01 {
     public static void main(String[] args) throws IOException {
         //1. 建立一个socket
         DatagramSocket socket = new DatagramSocket();
 
         //2. 建个包
         String msg = "你好";
         //发送给谁
         InetAddress localhost = InetAddress.getByName("localhost");
         int port = 9090;
         // 数据,数据的长度起始,发送给谁:ip,端口号
         DatagramPacket packet = new DatagramPacket(msg.getBytes(StandardCharsets.UTF_8), 0, msg.getBytes(StandardCharsets.UTF_8).length, localhost, port);
         //3. 发送包
         socket.send(packet);
    }
 }
 

接收端

 package com.kuang.lesson03;
 
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketException;
 
 //还是要等待客户端的连接
 public class UdpServerDemo01 {
     public static void main(String[] args) throws Exception {
         //开放端口
         DatagramSocket socket = new DatagramSocket(9090);
         //接受包
         byte[] bytes = new byte[1024];
         DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);//接收
         socket.receive(packet);//阻塞接收
 
         System.out.println(packet.getAddress().getHostAddress());
         System.out.println(new String(packet.getData(),0,packet.getLength()));
         //关闭连接
         socket.close();
    }
 }
 

循环发送消息

 package com.kuang.chat;
 
 import java.io.BufferedReader;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetSocketAddress;
 import java.net.SocketException;
 import java.nio.charset.StandardCharsets;
 import java.util.Scanner;
 
 public class UdpSenderDemo01 {
     public static void main(String[] args) throws Exception {
         DatagramSocket socket = new DatagramSocket(8888);
 
         //准备数据:控制台读取 {system.in}
         Scanner scanner = new Scanner(System.in);
         while (true){
             String data = scanner.next();
             byte[] datas = data.getBytes();
             DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,new InetSocketAddress("localhost",6666));
             socket.send(packet);
             if(data.equals("bye")){
                 break;
            }
        }
 
    }
 }
 

循环接收消息

 package com.kuang.chat;
 
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketException;
 
 public class UdpReceiveDemo01 {
     public static void main(String[] args) throws Exception {
         DatagramSocket socket = new DatagramSocket(6666);
 
 
         while (true){
             //准备接收包
             byte[] container = new byte[1024];
             DatagramPacket packet = new DatagramPacket(container, 0, container.length);
             socket.receive(packet);
 
             //断开连接 bye
             byte[] data = packet.getData();
             String datas = new String(data, 0, data.length);
 
             System.out.println(datas.trim());
 
             if(datas.trim().equals("bye")){
                 break;
            }
        }
    }
 }
 

在线咨询:两个人都可以是发送方,也可以是接收方

多线程 TalkReceive

 package com.kuang.chat;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetSocketAddress;
 import java.net.SocketException;
 import java.util.Scanner;
 
 public class TalkSend implements Runnable{
     DatagramSocket socket = null;
     Scanner scanner = null;
 
     private int fromPort;
     private String toIP;
     private int toPort;
 
     public TalkSend(int fromPort, String toIP, int toPort) throws Exception {
         this.fromPort = fromPort;
         this.toIP = toIP;
         this.toPort = toPort;
 
         socket = new DatagramSocket(fromPort);
         scanner = new Scanner(System.in);
    }
 
     @Override
     public void run() {
         while (true){
             try {
                 String data = scanner.next();
                 byte[] datas = data.getBytes();
                 DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,new InetSocketAddress(this.toIP,this.toPort));
                 socket.send(packet);
 
                 if(data.equals("bye")){
                     break;
                }
            } catch (IOException e) {
                 e.printStackTrace();
            }
        }
    }
 }
 

多线程 TalkSend

 package com.kuang.chat;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketException;
 import java.util.Scanner;
 
 public class TalkReceive implements Runnable{
     DatagramSocket socket = null;
     private int port;
     private String msgFrom;
 
     public TalkReceive(int port, String msgFrom) throws SocketException {
         this.port = port;
         this.msgFrom = msgFrom;
         socket = new DatagramSocket(port);
    }
 
     @Override
     public void run() {
 
         while (true){
             try {//准备接收包
                 byte[] container = new byte[1024];
                 DatagramPacket packet = new DatagramPacket(container, 0, container.length);
 
                 socket.receive(packet);
 
 
                 //断开连接 bye
                 byte[] data = packet.getData();
                 String datas = new String(data, 0, data.length);
 
                 System.out.println(this.msgFrom + ":" + datas.trim());
 
                 if(datas.trim().equals("bye")){
                     break;
                }
            } catch (IOException e) {
                 e.printStackTrace();
            }
        }
    }
 }

老师:

 package com.kuang.chat;
 
 public class TalkTeacher {
     public static void main(String[] args) throws Exception {
         //开启两个线程
         new Thread(new TalkSend(5555,"localhost",8888)).start();
         new Thread(new TalkReceive(9999,"学生")).start();
    }
 }

 

学生:

 package com.kuang.chat;
 
 public class TalkStudent {
     public static void main(String[] args) throws Exception {
         //开启两个线程
         new Thread(new TalkSend(7777,"localhost",9999)).start();
         new Thread(new TalkReceive(8888,"老师")).start();
    }
 }

1.8 URL

https://www.baidu.com/

统一资源定位符:定位资源的,定位互联网上的某一个资源

DNS 域名解析 www.baidu.com xxx.x..x..x

 协议://ip地址:端口号/项目名/资源

 

posted @ 2022-02-22 22:03  Bilia  阅读(74)  评论(0编辑  收藏  举报