面向网络编程

1.1、概述

打电话 --连接-- 接了—通话 TCP
发短信 --发送了就完事了 --接收 UDP

计算机网络:

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

网络编程的目的:

无线电台…传播交流信息——数据交换。通信

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

  1. 如何准确的定位网络上的一台主机 IP地址:端口,定位到这个计算机上某个资源
  2. 找到这个主机,如何传输数据呢?
    javaweb: 网页编程
    网络编程: TCP/IP

1.2、网络通信的要素

如何实现网络的通信?
通信双方的地址:

  • ip
  • 端口号
  • 192.168.124:5900
    规则:网络通信的协议
    在这里插入图片描述
    小结:
  1. 网络编程中有两个主要的问题
  • 如何准确的定位到网络上的一台或者多台主机
  • 找到主机之后如何进行通信
  1. 网络编程中的要素
  • IP和端口号——IP
  • 网络通信协议 ——TCP/UDP
  1. 万物皆对象

1.3、IP

IP地址:InetAddress

  • 唯一定位一台网络上的计算机
  • 127.0.0.1:本机localhost——ip
  • IP地址的分类:
    • IP地址分类:ipv4/ipv6
    • 公网和私网
      ipv4
      127.0.0.1,4个字节组成,0~255,42亿——2011年已用尽
      ipv6
      fe80::e39b:9fc3:2472:b4f6%8——128位,8个无符号整数
      公网(互联网)-私网(局域网)
      192.168.xx.xx,专门给组织内部使用的局域网
      域名:记忆ip问题
//测试ip
public class TestInetAddress{
   public static void main(String[] args){
     try{
     //查询本机地址
       InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
       System.out.println(inetAddress1);
       //查询网站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();
       }
   }
}

1.4、端口

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

  • 不同的进程有不同的端口号,用来区分软件
  • 被规定0~65535个端口号
  • TCP,UDP:65535*2 TCP:80,UDP:80——单个协议下,端口号不能冲突
  • 端口分类
    • 公有端口 0~1023——==http:80 https:443 ftp:21 ==
    • 程序注册端口:1024~49151——分配给用户或者程序 Tomcat:8080 MySQL:3306 Oracle:1521
    • 动态 ,私有 :49152~65535
netstat -ano  #查看所有的端口
netstat -ano|findstr "5900"  #查看指定端口
tasklist|findstr "8696"   #查看指定端口的进程
public class TestInetSocketAddress{
    public static void main(String[] args){
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
        System.out.println(socketAddress);
        
       System.out.println(socketAddress.getAddress());
       System.out.println(socketAddress.getHostName());//地址
       System.out.println(socketAddress.getPort());//端口
    }
}

1.5、通信协议

协议: 约定,就好比我们现在说的是普通话
**网络通信协议:**速率,传输码率,代码结构,传输控制…
**问题:**非常的复杂
大事化小:分层
TCP/IP协议簇:实际上十一组协议
重要:

  • TCP:用户传输协议
  • UDP:用户数据报协议
  • IP:网络互联协议
    在这里插入图片描述

TCP UDP对比

TCP:打电话

  • 连接,稳定
  • 三次握手,四次挥手
  • 客户端、服务端
  • 传输完成,释放连接,效率低

UDP:发短信

  • 不连接,不稳定
  • 客户端、服务端:没有明确的界限
  • 不管有没有准备好,都可以发给你…
  • DDOS:洪水攻击——造成端口阻塞——饱和攻击
三次握手 四次挥手

三次握手:
最少需要三次,保证稳定连接
A:你愁啥?
B:瞅你咋地
A:干一架
四次挥手:
A:我要走了
B:你真的要走了吗
B:你真的真的要走了吗
A:我真的要走了

1.6、TCP

客户端:

  1. 连接服务器Socket
  2. 发送消息
public class TcpClientDemo01{
   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("你好,欢迎学习网络编程".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. 等待用户的连接——accept
  3. 接收用户的消息
public class TcpServerDemo01{
   public static void main(String[] args){
   ServerSocket serverSocket = null;
   Socket socket = null;
   InputStream is = null;
   ByteArrayOutputStream baos = null;
    try{
    //1.我得有一个地址
    serverSocket  = new ServerSocket(9999);
    while(true){
       //2.等待客户端连接过来
       socket = serverSocket.accept();
       //3.读取客户端的消息
       is = socket.getInputStream();
    /*
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
         String msg = new String(buffer,0,len);
         System.out.pintln(msg);
        }
    */
       //管道流
       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()); 
      }
    }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 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("xx.jpg"));
       //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(buffer,0,len2);
       }
       
       System.out.println(baos.toString());

       //5.关闭资源
       baos.close();
       inputStream.close();
       fis.close();
       os.close();
       socket.close();
    }
}
服务器接收文件
public class TcpServerDemo02{
   public static void main(String[] args) throws Exception{
      //1.创建服务
      ServerSocket  serverSocket = new ServerSocket(9000);
      //2.监听客户端的连接
      serverSocket.accept();//阻塞式监听,会一直等待客户端连接
      //3.获取输入流
      InputStream is = socket.getInputStream();
      //4.文件输入
      FileOutputStream fos = new FileOutputStream(new File("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());
      //关闭资源
      fos.close();
      is.close();
      socket.close();
      serverSocket.close();
   }
}

Tomcat

服务端

  • 自定义 S
  • Tomcat服务器 S —— java后台开发

客户端

  • 自定义 C
  • 浏览器 B

1.7、UDP

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

发送消息

//不需要连接服务器
public class UdpClientDemo01{
    public static void main(String[] args) throws Exception{
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();
        
        //2.建个包
        String msg = "Hello 你好啊服务器";
        //发送给谁
        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 class UdpServerDemo01{
      public static void main(String[] args) throws Exception{
          //开放端口
          DatagramSocket socket = new DatagramSocket(9090);
          //接收数据包
          byte[] bytes = new byte[1024];
          DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);//接收
          socket.receive(packet);//阻塞接收
          System.out.println(packet.getAddress().getHostAddress());
          System.out.println(new String(packet.getData(),0,packet.length()));
          //关闭连接
          socket.close();
      }
}

聊天

循环发送消息:

public class UDPSenderDemo01{
     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 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 receiceData = new String(data,0,data.length);
            System.out.println(receiveData);
            if(receiveData.equals("bye")){
                break;
            }
         }
         socket.close();
     }
}

多线程聊天

发送线程
public class TalkSend implements Runable{
DatagramSocket socket = null;
BufferedReader reader = null;
private String toIp;//Ip
private int toPort;//端口号
private int fromPort;


public TalkSend(int fromPort,int toPort,String toIp){
    this.fromPort = fromPort;
    this.toPort = toPort;
    this.toIp = toIp;
    try{
       socket = new DatagramSocket(fromPort);
       //准备数据:  控制台读取 System.in
       reader = new BufferedReader(new InputStreamReader(System.in));
    }catch(Exception e){
       e.printStackTrace();
    }   
  }
     public void run(){
         try{
             //发送多条语句
          while(true){
             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();
     }
}
接收线程
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(port);
       //准备数据:  控制台读取 System.in
       reader = new BufferedReader(new InputStreamReader(System.in));
    }catch(Exception e){
       e.printStackTrace();
    }
 }
   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 receiceData = new String(data,0,data.length);
               System.out.println(msgFrom+":"+receiveData);
               if(receiveData.equals("bye")){
                   break;
               }
            }catch()
         }
         socket.close();
   }
}
开启线程
public class TalkStudent{
    public static void main(String[] args){
        //开启两个线程
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}
public class TalkTeacher{
     public static void main(String[] args){
        //开启两个线程
        new Thread(new TalkSend(5555,"localhost",8888)).start();
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}

1.8、URL

统一资源定位符:定位资源的,定位互联网上的某一个资源
DNS域名解析 —— 把域名变成IP
协议://ip地址:端口号/项目名/资源

public class URLDemo01{
     public static void main(String[] args) throws MalformeURLException {
         URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=fwl&password=123");
         System.out.println(url.getProtocol());//协议
         System.out.println(url.getHost());//主机ip 
         System.out.println(url.getPort());//端口
         System.out.println(url.getPath());//文件地址
         System.out.println(url.getFile());//文件全路径
         System.out.println(url.getQuery());//参数
     }
}

下载

public class UrlDown{
     public static void main(String[] args) throws Exception {
         //1.下载地址
         URL url = new URL("http://localhost:8080/FWL/HYL.txt");
         //2.连接到这个资源   HTTP
         HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
         InputStream inputStream = urlConnection.getInputStream();
         FileOutputStream fos = new FileOutputStream("HYL.txt") ;
         byte[] buffer = new byte[1024];
         int len;
         while((len = inputStream.read(buffer)) != -1){
             fos.write(buffer,0,len);//写出数据
         }
         fos.close();
         inputStream.close();
         urlConnection.disconnect();//断开连接
     }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值