java网络编程Scoket

155 阅读4分钟

网络编程

API

  1. 获取InetAddress对象,使用API

           //1.获取本机的InetAddress对象
           InetAddress localHost=InetAddress.getLocalHost();
    
  2. 根据指定的主机名/域名,获取InetAddress对象 getname()

           //2.根据指定的主机名,获取InetAddress对象
           InetAddress host = InetAddress.getByName("LAPTOP-ULAQ4LFT");
           System.out.println("host="+host);
           //3.根据域名返回InetAddress对象,比如 www.baidu.com
           InetAddress host2 = InetAddress.getByName("www.baidu.com");
           System.out.println("host="+host2);
    
  3. 通过InetAddress对象,获取对应的地址

    System.out.println("ip="+host2.getHostAddress()); 
    
  4. 通过InetAddress对象,获取服务器名字

    System.out.println("ip="+host2.getHostName()); 
    

Socket

  • 基本介绍

    1. 套接字开发网络应用程序被广泛采用,以至于成为事实上的标准
    2. 通信的两端都要Socket,是两台机器通信的端点
    3. 网络通信就是Socket之间的通信
    4. Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
    5. 一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
  • TCP

    • 创建连接 (服务器端)

              //创建服务器连接
              ServerSocket serverSocket = new ServerSocket(9999);
              //等待连接    进行阻塞
              Socket socket = serverSocket.accept();
      
    • socket可以获取字节流等方法

    • 接收连接 (客户端)

              //创建连接
              Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
      
  • UTP

    • 说明

      1. 没有明确的服务端和客户端,演变数据的发送端和接收端
      2. 接收数据和发送数据是通过DatagramSocket对象完成的
      3. 将数据封装到DatagramPacket对象/装包
      4. 当接收到DatagramPacket对象,需要进行拆包,取出数据
      5. DatagramScoket可以指定在哪一个端口接收数据
    • 基本流程

      1. 核心DatagramScoket,DatagramPack
      2. 建立发送端,接收端
      3. 建立数据包
      4. 调用DatagramSocket的发送,接收方法
      5. 关闭
    • 发送

      创建一个发送包 在里面放入内容接收端的ip和端口,通过socket.sent(page)发送

              //创建DatagramScoket对象 准备发送和接收数据   准备在9998接收数据
              DatagramSocket socket = new DatagramSocket(9998);
              //将需要发送的数据,封装到DatagramPacket对象
              byte[] bytes = "holle,数据来了".getBytes();
              //把数据(字节)发送到   InetAddress.getLocalHost()本机   端口:9999
              DatagramPacket dataPacket = new DatagramPacket(bytes, bytes.length,     InetAddress.getLocalHost(), 9999);
              //发送
              socket.send(dataPacket);
              //关闭
              socket.close()
      
    • 接收

      创建一个接收包 放入容器byte[] 和长度,socket.receive(page)进行接收

              //创建一个DatagramSocket 对象,准备接收数据
              DatagramSocket socket = new DatagramSocket(9999);
              //准备接收数据
              byte[] bytes=new byte[1024];
              //打包
              DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
              //调用接收方法    将通过网络传输的DatagramPacket对象填充到packet对象中
              /**
               * 如果有数据发送到本机的9999端口时,就会接收数据
               * 如果没有数据包发送到本机的9999端口,就会阻塞
               */
              System.out.println("接收端等待中.....");
              socket.receive(packet);
              
              
              //可以把packet数据进行拆包,取出数据并显示
              int length=packet.getLength();//实际接收到的数据长度
              byte[] data= packet.getData();//获取数据
              String s = new String(data, 0, length);
              System.out.println("数据已经收到了=>"+s);
              socket.close()
      
  • 注意点

    • 两个Socket在进行通信时,无法确认对方是否写入完毕,需要设置一个结束标记

      1. shutdown() 用来关闭连接,而不是套接字,不管调用多少次 shutdown(),套接字依然存在,直到调用 close()
      2. 单向的socket便称为半开放Socket。要实现半开放式,需要用到shutdown()函数。
      3. 当你使用shoutdownoutput作为结束 接收端会读到最后会返回一个-1
      4. 调用Socket.shutdownOutput()后,禁用此套接字的输出流 ,后续无法在进行输入
              //设置输出结束标记
              socket.shutdownOutput();
      
    • 使用通过字符流输出客户端时,输出完毕后,一定要刷新,不然会报错

              //记得刷新,不然会报错
              out.flush();
      

      刷新就是将内存(缓冲区)中的数据(是一个字节数组)强制写到磁盘/浏览器/控制台/文件

    • 当客户端连接到服务器后,实际上客户端也是通过一个端口和服务端进行通信的,这个端口是TCP/IP来分配的,是不确定的,是随机的

    • 要想实现双端循环输入两方必须约定以一个什么字符作为一次读取的结尾比如换行符,才可以循环读取,不能用shotdownoutput()

\