网络编程

网络编程

javaweb 网页编程:B/S

网络编程:TCP/IP C/S

TCP/IP参考模型:

 

 

 

问题:

  1. 定位网络上的一台或者多台主机

  2. 找到主机之后,如何进行通信

网络编程中的要素:

  • IP 和端口号

  • 网络通信协议

 

IP

IP地址:InetAddress

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

  • 127.0.0.1:本机 localhost

  • IP地址分类

    • IPV4 / IPV6

      • IPV4 127.0.0.1,四个字节组成。0 - 255,42亿左右的地址。30亿在北美,亚洲4亿。2011年就用尽了;

      • IPV6 fe80::f4ea:b072:3e83:fed7%14,128位。8个无符号整数!用不完

             2001:0bb2:aaaa:0015:0000:0000:1aaa:1312(伪造)
    • 公网(互联网) / 私网(局域网)

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

      • A、B、C、D类地址

  • 域名:记忆 IP 问题!

 //测试IP
 public class TestInetAddress {
     public static void main(String[] args) {
         try {
 
             //查询本机地址
             InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
             System.out.println(inetAddress1);
             InetAddress inetAddress3 = InetAddress.getByName("localhost");
             System.out.println(inetAddress3);
             InetAddress inetAddress4 = InetAddress.getLocalHost();
             System.out.println(inetAddress4);
 
             //查询网站 ip 地址
             InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
             System.out.println(inetAddress2);
 
             //常用方法
             System.out.println(inetAddress2.getAddress());  //返回一组地址,一般没什么用
             System.out.println(inetAddress2.getCanonicalHostName());    //规范的名字,没什么用
             System.out.println(inetAddress2.getHostAddress());  //获得ip
             System.out.println(inetAddress2.getHostName()); //获得域名,或者是本机的名字
        } catch (UnknownHostException e) {
             e.printStackTrace();
        }
    }
 }

 

端口

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

  • 不同的进程有不同的端口号!用来区分软件!

  • 端口被规定0 - 65535

  • TCP,UDP:65535*2;TCP用了端口8080,UDP还能用。单个协议下,端口不能冲突

  • 端口分类

    • 公有端口:0 - 1023

      • HTTP:80

      • HTTPS:443

      • FTP:21

      • TELENT:23

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

      • Tomcat:8080

      • MySQL:3306

      • Oracle:1521

      • SQLServer:1633

    • 动态、私有:49152 - 65535

           netstat -ano # 查看所有的端口
        netstat -ano|findstr "5900" #查看指定的端口
        tasklist|findstr "8696" #查看指定端口的进程
        Ctrl + shift + ESC
           public static void main(String[] args) {
               InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080);
               InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost",8080);
               System.out.println(inetSocketAddress);
               System.out.println(inetSocketAddress2);
       
               System.out.println(inetSocketAddress.getAddress());
               System.out.println(inetSocketAddress.getHostName());    //地址
               System.out.println(inetSocketAddress.getPort());        //端口
          }

 

通信协议

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

网络协议:速率、传输码率、代码结构、传输控制.......

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

重要:

  • TCP:用户传输协议

  • UDP:用户数据报协议

  • IP:网络互连协议

 

TCP VS UDP

TCP:打电话

  • 连接、稳定

  • 三次握手,四次挥手

         最少需要三次,保证稳定连接!
      A:你瞅啥?
      B:瞅你咋地?
      A:干一场!
     
      A:我断开了
      B:你要断开了?
      B:你真的断开了?
      A:我真的断开了

     

  • 客户端、服务端

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

UDP:发短信

  • 不连接、不稳定

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

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

  • DDOS:洪水攻击(饱和攻击)

 

TCP

客户端:

  1. 连接服务器,通过Socket

  2. 发送消息

         public static void main(String[] args) {
     
             Socket socket = null;
             OutputStream os = null;
     
             try {
                 //1、要知道服务器的地址,端口号
                 InetAddress serverIP = InetAddress.getByName("127.0.0.1");
                 int port = 9999;
     
                 //2、创建一个 socket 连接
                 socket = new Socket(serverIP,port);
     
                 //3、发送消息 IO 流
                 os = socket.getOutputStream();
                 os.write("Hello world!".getBytes());
     
            } catch (Exception e) {
                 e.printStackTrace();
            }finally {
                 if(os != null){
                     try {
                         os.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
     
                 if(socket != null){
                     try {
                         socket.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
            }
     
        }

     

服务器:

  1. 建立服务器的端口:ServerSocket

  2. 等待用户的连接:accpet

  3. 接受用的消息

         public static void main(String[] args) {
     
             ServerSocket serverSocket = null;
             Socket socket = null;
             InputStream is = null;
             ByteArrayOutputStream baos = null;
     
             try {
                 //1、我得有一个地址
                 serverSocket = new ServerSocket(9999);
     
                 //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);
            } catch (IOException e) {
                 e.printStackTrace();
            }finally {
                 //关闭资源
                 if (baos != null) {
                     try {
                         baos.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
     
                 if(is != null){
                     try {
                         is.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
     
                 if(socket != null){
                     try {
                         socket.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
     
                 if(serverSocket != null){
                     try {
                         serverSocket.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
                }
            }
     
        }

     

文件上传

客户端:

     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("1.png");
         //4、写出文件
         byte[] buffer = new byte[1024];
         int len;
         while((len = fis.read(buffer)) != -1){
             os.write(buffer,0,len);
        }
 
         //通知服务器,我已经传输完了
         socket.shutdownOutput();
 
         //确定服务器接收完毕,才能断开连接
         InputStream inputStream = socket.getInputStream();
         //String byte[]
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
         byte[] buffer2 = new byte[1024];
         int len2;
         while((len2 = inputStream.read(buffer2)) != -1){
             baos.write(buffer2,0,len2);
        }
         System.out.println(baos.toString());
 
         //5、关闭资源
         baos.close();
         inputStream.close();
         fis.close();
         os.close();
    }

 

服务端:

     public static void main(String[] args) throws Exception {
         //1、创建服务
         ServerSocket serverSocket = new ServerSocket(9000);
 
         //2、监听客户端的连接
         Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户段连接
 
         //3、获取输入流
         InputStream is = socket.getInputStream();
 
         //4、文件输出
         FileOutputStream fos = new FileOutputStream(new File("receive.png"));
         byte[] buffer = new byte[1024];
         int len;
         while((len = is.read(buffer)) != -1){
             fos.write(buffer,0,len);
        }
 
         //通知客户端我接收完毕了
         OutputStream os = socket.getOutputStream();
         os.write("receive over!".getBytes());
 
         //关闭资源
         os.close();
         fos.close();
         is.close();
         socket.close();
         serverSocket.close();
 
    }

 

Tomcat

CS,BS

服务端:

  • 我们可以自定义:S

  • 可以使用 Tomcat 服务器:S

客户端:

  • 可以自定义:C

  • 可以使用浏览器:B

 

UDP

发短信:不用连接,需要知道对方的地址。不存在真正意义上的服务端和客户端。

客户端:

 
     //不需要连接服务器(也不会报错,但是送到哪就不知道了,所以要创建一个地址来接收)
     public static void main(String[] args) throws Exception {
         //1、建立一个Socket
         DatagramSocket socket = new DatagramSocket();
 
         //2、建个包
         String msg = "Hello,Server!";
         
         //发送给谁
         InetAddress localhost = InetAddress.getByName("localhost");
         int port = 9090;
         
         // 数据,数据的长度其实,需要发送给谁
         DatagramPacket packet =
             new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
 
         //3、发送包
         socket.send(packet);
 
         //4、关闭流
         socket.close();
    }
 

服务端:

 //还是要等待客户端的连接
  public static void main(String[] args) throws Exception {
         //开放端口
         DatagramSocket socket = new DatagramSocket(9090);
 
         //接收数据包
         byte[] buffer = new byte[1024];
         DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
 
         //阻塞接收
         socket.receive(packet);
 
         //关闭连接
         socket.close();
    }

 

发送消息

循环发送消息

     public static void main(String[] args) throws Exception {
 
         DatagramSocket socket = new DatagramSocket(8888);
 
         //准备数据: 控制台读取 System.in
         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 
         while(true){
             String data = reader.readLine();
             byte[] datas = data.getBytes();
             DatagramPacket packet =
                 new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
 
             socket.send(packet);
 
             if(data.equals("bye")){
                 break;
            }
        }
 
         socket.close();
 
    }

 

循环接收消息

     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);//阻塞式接收包裹
             
             //显示消息
             byte[] data = packet.getData();
             String receiveData = new String(data, 0, data.length);
             
             System.out.println(receiveData);
             
             //断开连接 bye
             if(receiveData.equals("bye")){
                 break;
            }
        }
         
    }

 

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

 

TalkSend发送类:

 public class TalkSend implements Runnable{
     DatagramSocket socket = null;
     BufferedReader reader = null;
 
     private int fromPort;
     private String toIP;
     private int toPort;
 
     public TalkSend(int fromPort, String toIP, int toPort) {
         this.fromPort = fromPort;
         this.toIP = toIP;
         this.toPort = toPort;
 
         try {
             socket = new DatagramSocket(fromPort);
             reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
             e.printStackTrace();
        }
    }
 
     @Override
     public void run() {
 
         while(true){
             try {
                 String data = reader.readLine();
                 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 (Exception e) {
                 e.printStackTrace();
            }
        }
 
         socket.close();
    }
 }

TalkReceive接收类:

 public class TalkReceive implements Runnable{
     DatagramSocket socket = null;
     private int port;
     private String msgFrom;
 
     public TalkReceive(int port, String msgFrom) {
         this.port = port;
         this.msgFrom = msgFrom;
         try {
             socket = new DatagramSocket(this.port);
        } catch (SocketException e) {
             e.printStackTrace();
        }
    }
 
     @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 receiveData = new String(data, 0, data.length);
 
                 System.out.println(msgFrom+":"+receiveData);
 
                 if(receiveData.equals("bye")){
                     break;
                }
 
            } catch (IOException e) {
                 e.printStackTrace();
            }
 
        }
 
         socket.close();
    }
 }

学生端:

 public static void main(String[] args) {
     //开启两个线程,从7777端口 发到9999端口
     new Thread(new TalkSend(7777,"localhost",9999)).start();
     //在8888端口接收老师消息
     new Thread(new TalkReceive(8888,"老师")).start();
 }

老师端:

 public static void main(String[] args) {
     //开启两个线程,从5555端口 发到8888端口
     new Thread(new TalkSend(5555,"localhost",8888)).start();
     //在9999端口接收学生消息
     new Thread(new TalkReceive(9999,"学生")).start();
 }

 

URL

百度一下,你就知道 (baidu.com)

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

DNS:域名解析百度一下,你就知道 (baidu.com)把这个域名变成 ip 地址


 协议://ip地址:端口号/项目名/资源
 public static void main(String[] args) throws Exception {
         //前提是要将当前的资源处于一个开启的状态
         //1、下载地址
 //       URL url = new URL("此处填写下载的地址");
         URL url = new URL("https://m701.music.126.net/20220701210846/4bd39b507daf2ab41b61f3bd66a2353e/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/15081270189/c2dd/8993/9b45/3ceae4164e9a77b267408087bae1a93f.m4a");
 
         //2、连接到这个资源
         HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
 
         InputStream inputStream = urlConnection.getInputStream();
 
 //       FileOutputStream fos = new FileOutputStream("此处填写文件名,例:xxx.txt");
         FileOutputStream fos = new FileOutputStream("f.m4a");
 
         byte[] buffer = new byte[1024];
         int len;
         while((len = inputStream.read(buffer)) != -1){
             fos.write(buffer,0,len);//写出这个数据
        }
 
         fos.close();
         inputStream.close();
         urlConnection.disconnect();
    }
 
posted @ 2022-07-01 20:57  小gun  阅读(143)  评论(0)    收藏  举报