crushS  

网络编程

1.1网络通信的要素

通信双方地址:

  • ip

  • 端口号

规则:网络通信协议

TCP/IP参考模型:

OSI七层模型

1.2 IP

ip地址:InetAddress

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

  • 127.0.0.1 :本机(localhost)

  • ip地址的分类

    • ipv4/ipv6

      • ipv4 127.0.0.1,4个字节组成,范围 0~255

      • ipv6 128位,8个无符号整数

    • 公网(互联网)、私网(局域网)分类

      • ABCD类地址

      • 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);
           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.getCanonicalHostName());//规范的名字
           System.out.println(inetAddress2.getHostAddress());//ip
           System.out.println(inetAddress2.getHostName());//域名,或者自己电脑的名字
      } catch (UnknownHostException e) {
           e.printStackTrace();
      }
  }
}

1.3 端口

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

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

  • 被规定0~65535

  • TCP、UDP:65535*2 TCP用了80端口,UDP也可以用80端口,这两个协议不冲突。单个协议下,端口号不能冲突。

  • 端口分类

    • 公有端口 0~1023

      • HTTP: 80

      • HTTPS: 443

      • FTP: 21

      • Telnet: 23

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

      • Tomcat: 8080

      • MySQL: 3306

      • Oracle: 1521

    • 动态、私有:49152~65535

      netstat -ano #查看所有的端口
      netstat -ano|findstr "5900" #查看指定的端口
      tasklist|findstr "8696" #查看指定端口的进程
      Ctrl+shift+ESC #打开任务管理器

       

1.4通信协议

TCP/IP(网络互连协议)协议簇:实际上是一组协议

重要:

  • TCP:用户传输协议

  • UDP:用户数据报协议

TCP UDP 对比

TCP:打电话

  • 连接,稳定

  • 三次握手 四次挥手具体内容

  • 客户端、服务端

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

UDP:发短信

  • 不连接,不稳定

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

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

  • DDOS:分布式拒绝服务攻击(洪水攻击)

1.5 TCP实现聊天

客户端

  1. 连接服务器 Socket

  2. 发送消息

package com.kuang.leson02;


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) {
       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. 接收用的消息

package com.kuang.leson02;

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) {
       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();
           // 4.管道流
          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();
            }
        }
      }
  }
}

1.6 TCP文件上传实现

客户端读取文件,服务端接收文件

package com.kuang.leson02;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//客户端
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("BasicGrammar/lib/a.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(buffer2,0,len2);
      }
       System.out.println(baos.toString());
       // 关闭资源
       baos.close();
       inputStream.close();
       fis.close();
       os.close();
       socket.close();
  }
}
package com.kuang.leson02;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//服务器端
public class TcpServerDemo02 {
   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("BasicGrammar/lib/d.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

1.7 UDP

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

发送端

package com.kuang.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

//不需要连接服务器
public class UdpDemo01 {
   public static void main(String[] args) throws Exception {
       //1. 建立一个Socket
       DatagramSocket socket = new DatagramSocket();
       //2. 建个包
       String msg = "上海疫情早日清零";
       //发送给谁
       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();
  }
}

接收端

package com.kuang.lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdoDemo02 {
   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);//阻塞接收
       System.out.println(packet.getAddress().getHostName());
       System.out.println(new String(packet.getData(),0,packet.getLength()));
       //关闭连接
       socket.close();
  }
}

单向聊天

循环发送消息

package com.kuang.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpSenderDemo01 {
   public static void main(String[] args) throws Exception {
       DatagramSocket socket = new DatagramSocket(8888);
       while(true){
           //准备数据:控制台读取 System.in
           BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
           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("byebye")){
               break;
          }
      }

       socket.close();

  }
}

循环接收消息

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

      }
       socket.close();
  }
}

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

发送线程

package com.kuang.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

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(8888);
           reader = new BufferedReader(new InputStreamReader(System.in));
      } catch (Exception 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("byebye")){
                   break;
              }
          }catch(Exception e){
               e.printStackTrace();
          }

      }
       socket.close();
  }
}

接收线程

package com.kuang.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

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);
      } 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);//阻塞式接收包裹
               //断开连接
               byte[] data = packet.getData();
               String receiveData = new String(data, 0, data.length);
               System.out.println(msgFrom+":"+receiveData);
               if (receiveData.equals("byebye")) {
                   break;
              }
      }catch(Exception e){
           e.printStackTrace();
      }
   
       socket.close();
  }
}

二者对话

package com.kuang.chat;

public class teacherTalk {
   public static void main(String[] args) {
       new Thread(new talkSend(5554,"localhost",6060)).start();
       new Thread(new talkReceive(9999,"学生")).start();
  }
}
package com.kuang.chat;

public class studentTalk {
   public static void main(String[] args) {
       new Thread(new talkSend(7777,"localhost",9999)).start();
       new Thread(new talkReceive(6060,"老师")).start();
  }
}

1.8 URL(统一资源定位符)

 

posted on 2021-08-12 21:28  crushS  阅读(38)  评论(0编辑  收藏  举报