Java Socket 套接字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zcpvn/article/details/81331588


基础知识

网络的三要素:

  • 1)IP地址
    • 每个设备在网络中的唯一标识。
    • 每台网络终端终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。
  • 2)端口号

    • 既然IP地址可以找到一个唯一的设备,那么端口号就是每个程序在设备上的唯一标识。
    • 每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。
    • 端口号范围是0 ~ 65536,其中0 ~ 1023是系统程序占用的,例如:
    端口号 名称 注释
    21 ftp 文件传输协议端口
    22 ssh 安全 Shell 服务
    80 http 用于万维网(WWW)服务的超文本传输协议
    443 https 安全超文本传输协议

    更多详细端口看这里

  • 3)网络协议

    • 为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
    • UDP
      • 面向无连接,数据不安全,速度相比TCP快。
      • 不区分客户端与服务端,只区分发送端和接收端。
    • TCP
      • 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
      • 三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据。

Socket 的定义

  • 即套接字,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,表现为一个封装了 TCP / IP协议族 的编程接口(API)图
  1. Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)。
  2. 即:通过Socke,我们才能在Java、Andorid平台上通过 TCP/IP协议进行开发。
  3. 对用户来说,只需调用Socket去组织数据,以符合指定的协议,即可通信。
  • 一个Socket实例,唯一代表一个主机上的一个应用程序的通信链路。
  • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
  • 通信的两端都有Socket
  • 网络通信其实就是Socket间的通信。
  • 数据在两个Socket间通过IO流传输。
  • Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IPport

UDP

UDP(User Datagram Protocol),也就是用户数据包协议。关键点在于“数据包”。主要就是把数据进行打包然后丢给目标,而不管目标是否接收到数据。

使用UDP传输的类是DatagramSocket,构造方法如下:
UDP构造方法

  • 空参构造方法表示随机分配一个端口号。
  • 参数中的 SocketAddress == InetAddress + port
  • 创建数据报套接字并将其绑定到本地主机上的IP和指定端口

使用DatagramPacket来包装数据,构造方法如下:
这里写图片描述

  • 第1个一般用来装接收的数据,用来接收长度为length的数据包。
  • 第2个用来用来将长度为length的包发送到指定主机上的指定端口号length参数必须小于等于buf.length

使用步骤

  • 1) 发送Send
    • 创建DatagramSocket, 指定发送端的端口号(空参表示随机,无法大量并发)
    • 创建DatagramPacket, 指定数据, 长度, 地址, 端口
    • 使用DatagramSocket发送DatagramPacket
    • 关闭DatagramSocket
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Test_Send {

    public static void main(String[] args) throws IOException {

        DatagramSocket socket = new DatagramSocket();   // 创建UDP Socket,此空参数构造使得发送端口号为随机端口,最好指定固定的
        Scanner scanner = new Scanner(System.in);

        while (true) {
            String line = scanner.nextLine();

            DatagramPacket packet = new DatagramPacket(     // 数据包
                    line.getBytes(),                        // 发送数据的字节数组
                    line.length(),                          // 发送
                    InetAddress.getLocalHost(),             // 向本地IP发送,因为两个程序在一起
                    1314);                                  // 指定目标端口

            socket.send(packet);                            // 发送

            if ("quit".equals(line)) {                      // 发送quit后则结束
                break;
            }
        }
        scanner.close();
        socket.close();
    }

}
  • 2) 接收Receive
    • 创建DatagramSocket, 指定端口号
    • 创建DatagramPacket, 指定数组, 长度
    • 使用DatagramSocket接收DatagramPacket
    • 关闭DatagramSocket
    • 从DatagramPacket中获取数据
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Test_Receive {

    public static void main(String[] args) throws IOException {

        DatagramSocket socket = new DatagramSocket(1314);

        while (true) {
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
            socket.receive(packet);

            byte[] data = packet.getData();
            int len = packet.getLength();
            String str = new String(data,0,len);

            if ("quit".equals(str)) {                       // 接收到quit后则结束
                break;
            }

            System.out.println(str);
        }

        socket.close();
    }

}
  • 3) 运行结果:
    • 发送端:
      这里写图片描述
    • 接收端:
      这里写图片描述
  • 接收方获取ip和端口号的方法
    • String ip = packet.getAddress().getHostAddress();
    • int port = packet.getPort();

下一篇是TCP

猜你喜欢

转载自blog.csdn.net/zcpvn/article/details/81331588