概述

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

  • 网络编程目的:无线电,数据交互,通信,传播交流信息

网络通信要素

IP

端口

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

    • 不同的进程有不同的端口号,原来区分软件
    • 被规定0~65535
    • 单个协议下,端口号不能冲突
    • 端口分类:
      1. 公有端口: 0~1023
      2. HTTP: 80
      3. HTTPS: 443
      4. FTP: 21
      5. TELENT: 23
      6. 程序注册端口:1024~49151,分配用户或者程序
        • Tomcat: 8080
        • MySQL: 3306
        • Oracle: 1521
  • 动态、私有:49152~65535

    1
    2
    3
    netsata -ano #查看所有的端口
    netsata -ano|findstr "5900" #查看指定的端口
    tastlist|findstr "8696" #查看指定端口的进程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class TestInetSocketAddress {
    public static void main(String[] args) {
    InetSocketAddress socketAddress=new InetSocketAddress("127.0.0.1",8080);
    InetSocketAddress socketAddress2=new InetSocketAddress("localhost",8080);
    System.out.println(socketAddress);
    System.out.println(socketAddress2);

    System.out.println(socketAddress.getAddress());
    System.out.println(socketAddress.getHostName());//地址
    System.out.println(socketAddress.getPort());//端口
    }
    }

通信协议

TCP

  • 客户端

    • 连接服务器Socket

    • 发送消息

      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
      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.创建一个socke链接
      socket=new Socket(serverIP,port);
      //3.发送消息IO流
      os= socket.getOutputStream();
      os.write("helloworld".getBytes());
      } catch (IOException e) {
      e.printStackTrace();
      }finally {
      if(os!=null) {
      try {
      os.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      try {
      socket.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }
      }
  • 服务器

    • 建立服务的端口ServerSocket

    • 等待用户的链接accept

    • 接收用的消息

      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
      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();

      //管道流
      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 {
      is.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      if(socket!=null) {
      try {
      socket.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      if(is!=null) {
      try {
      serverSocket.close();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }
      }
      }
  • 文件上传

    • 客户端

      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
      public class TcpClientDemo02 {
      public static void main(String[] args) throws IOException {
      //创建一个Socket连接
      Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
      //创建一个输出流
      OutputStream outputStream = socket.getOutputStream();
      //读取文件
      FileInputStream fileInputStream = new FileInputStream(new File("d:/aaa.txt"));
      //写出文件
      byte[] buffer= new byte[1024];
      int len;
      while ((len=fileInputStream.read(buffer))!=-1){
      outputStream.write(buffer,0,len);
      }

      //通知服务器结束
      socket.shutdownOutput();//传输完毕

      //确定服务器接收完毕,才能断开连接
      InputStream inputStream = socket.getInputStream();
      ByteOutputStream byteOutputStream = new ByteOutputStream();
      byte[] buffer2 = new byte[1024];
      int len2;
      while ((len2=inputStream.read())!=-1){
      byteOutputStream.write(buffer2,0,len);
      }
      System.out.println(byteOutputStream.toString());
      //关闭资源
      byteOutputStream.close();
      outputStream.close();
      fileInputStream.close();
      socket.close();
      }
      }
  • 服务器

    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
    public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
    //创建服务
    ServerSocket serverSocket = new ServerSocket(9000);
    //监听客服端连接
    Socket accept = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
    //获取输入流
    InputStream inputStream = accept.getInputStream();
    //文件输出
    FileOutputStream fileOutputStream = new FileOutputStream("d:/receive.txt");
    byte[] buffer=new byte[1024];
    int len;
    while ((len=inputStream.read(buffer))!=-1){
    fileOutputStream.write(buffer,0,len);
    }
    //通知客户端接收完毕
    OutputStream outputStream = accept.getOutputStream();
    fileOutputStream.write("接收完毕,可以断开".getBytes());



    //关闭资源
    fileOutputStream.close();
    inputStream.close();
    accept.close();
    serverSocket.close();
    }
    }

UDP

  • 发短信

    ​ 不用连接,需要知道对方地址

    • 发送端

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      //不需要连接服务器
      public class UdpClientDemo01 {
      public static void main(String[] args) throws Exception {
      //1. 建立一个Socket
      DatagramSocket datagramSocket = new DatagramSocket();
      //2.建个包
      String msg="你好服务器";
      InetAddress localhost = InetAddress.getByName("localhost");
      int port=9090;

      //数据,数据长度起始,发送给谁
      DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);

      //发送包
      datagramSocket.send(datagramPacket);

      //关闭流
      datagramSocket.close();
      }
      }
  • 接收端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //要等待客户端的连接
    public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
    //开放端口
    DatagramSocket datagramSocket = new DatagramSocket(9090);
    //接收数据包
    byte[] buffer = new byte[1024];
    DatagramPacket datagramPacket = new DatagramPacket(buffer,0,buffer.length);

    datagramSocket.receive(datagramPacket);//阻塞接收
    System.out.println(datagramPacket.getAddress().getHostAddress());
    System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
    //关闭连接
    datagramSocket.close();

    }
    }
  • 循环发送消息

    • 发送端

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      public class UdpSendDemo01 {
      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();
      }
      }
  • 接收端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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 receiveData = new String(data, 0, data.length);
    System.out.println(receiveData);
    if(receiveData.equals("bye")){
    break;
    }
    }
    socket.close();
    }
    }
  • 在线咨询

    两个人既可以是发送端,也可以是接收端

    • 发送端

      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 TalkSend implements Runnable{

      DatagramSocket socket=null;
      BufferedReader Reader=null;
      private int fromIP;
      private String toIP;
      private int toPort;

      public TalkSend(int fromIP, String toIP, int toPort) {
      this.fromIP = fromIP;
      this.toIP = toIP;
      this.toPort = toPort;
      try{
      socket = new DatagramSocket(fromIP);
      Reader = new BufferedReader(new InputStreamReader(System.in));
      }catch(Exception e){
      e.printStackTrace();
      }
      }

      public void run(){
      while (true) {
      try {
      String data = Reader.readLine();
      byte[] datas = data.getBytes();
      DatagramPacket Packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(toIP, toPort));
      socket.send(Packet);
      if (data.equals("bye")) {
      break;
      }
      }catch (Exception e){
      e.printStackTrace();
      }
      }
      }
      }
  • 接收端

    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
    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);//阻塞式接收包裹
    //断开连接 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();
    }
    }
  • 学生

    1
    2
    3
    4
    5
    6
    7
    public class TalkStudent {
    //开启两个线程
    public static void main(String[] args) {
    new Thread(new TalkSend(7777,"localhost",9999)).start();;
    new Thread(new TalkReceive(8888,"老师")).start();
    }
    }
  • 老师

    1
    2
    3
    4
    5
    6
    public class TalkTeacher {
    public static void main(String[] args) {
    new Thread(new TalkSend(5555,"localhost",8888)).start();
    new Thread(new TalkReceive(9999,"学生")).start();
    }
    }