一.Socket套接字

Socket是一种通信机制,允许不同机器上的进程通过网络进行数据交换,他是应用层与传输层之间的桥梁,封装了TCP/IP族协议的细节

针对传输层协议分为三类:

1.流套接字:使用传输层TCP协议(Transmission Control Protocol)

                     特点:有连接,可靠传输,面向字节流

2.数据报套接字:使用传输层UDP协议(User Datagram Protocol)

                      特点:无连接,不可靠传输,面向数据报

3.原始套接字(不重要):⽤于⾃定义传输层协议,⽤于读写内核没有处理的IP协议数据

二..数据报套接字

在Java中,主要用 DatagramSocket 类来创建数字报套接字

DatagramSocket 构造方法:

1.无参

DatagramSocket socket = new DatagramSocket();

这种构造方法系统会自动分配一个端口号,适用于客户端和不需要固定端口的服务端。

2.固定端口号

DatagramSocket socket = new DatagramSocket(7721);

这种构造方法由程序员指定分配一个端口号,适用于服务端。

DatagramSocket相关方法:

1.void receive(DatagramPacket p)

用来接收数据报,如果没有接收到数据报,会进行阻塞等待。

2.void send(DatagramPacket p)

用来发送数据报(直接发送,不会阻塞等待)

3.void close

关闭数据包套接字

DatagramPacket

DatagramParket 是用来处理 UDP 数据的核心类

主要作用:

数据封装:将要发送或接收的数据打包成UDP数据包格式
地址管理:存储目标或源地址信息(IP地址和端口号)
缓冲区管理:管理数据的字节缓冲区

接收数据报构造方法:

1.DatagramPacket(byte[] buf,int length) 

buf :数据缓冲区,用于临时存放要发送的字节数据

length :缓冲区长度

2.DatagramPacket(byte[] buf,int offset,int length)

offset:缓冲区起始偏移量(offset 就是相当于数据的起始位置)

发送数据报的构造方法:

1.DatagramPacket(byte[] buf,int length,IntAddress address,int port)

address : 目标IP地址

port : 目标端口号

2.DatagramPacket(byte[] buf,int offset,int length,IntAddress address,int port)

DatagramPacket 相关方法:

IntAddress getAddress():

从接收的数据报中获取发送端主机的IP地址

int getPart():

从接收的数据报中获取发送端主机的端口号

byte[] getData():

获取数据报中的数据

IntSocketAddress:

SocketAddress 主要通过 IntSocketAddress 来构建。发送数据包的构建方法里面要用到SocketAddress

IntSocketAddress 构造方法

1.IntSocketAddress(IntAddress addr,int port)

addr:主机IP地址

port:端口号

实例代码演示:

UDP Echo Server : 服务端

import java.io.IOException;
import java.net.*;

public class EdpChoServe {
    private DatagramSocket socket = null;
    public EdpChoServe(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            //创建接收缓冲区DatagramPacket
            DatagramPacket requestparcket = new DatagramPacket(new byte[1024],1024);
            //接收客户端数据
            socket.receive(requestparcket);
            //将数据转化为字符串类型
            String request = new String(requestparcket.getData(),0, requestparcket.getLength());
            //将转化后的数据通过process方法进行处理(此处直接返回,如果要进行相关数据的处理直接修改process方法)
            String response = process(request);
            //再次创建DatagramPacket套接字,将加工的数据给客户端发送
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
                    response.getBytes().length,requestparcket.getSocketAddress());
            //发送数据
            socket.send(responsePacket);
            //打印客户端地址,端口,请求和相应信息
            System.out.printf("[%s:%d] req:%s,resp:%s\n",requestparcket.getAddress().toString(),
                    requestparcket.getPort(),request,response);
        }
    }
    private String process(String request){
        String response = "服务端返回的消息:"+request;
        return response;
    }

    public static void main(String[] args) throws IOException {
        EdpChoServe serve = new EdpChoServe(1010);
        serve.start();
    }
}

UDP Echo Client: 客户端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class EdpChoClient {
    private DatagramSocket socket = null;
    private String IP;
    private int Port;
    public EdpChoClient(String ip,int port) throws SocketException {
        socket = new DatagramSocket();
        this.IP = ip;
        this.Port = port;
    }
    public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner scanner = new Scanner(System.in);
        while (true){
            //输入要传输的内容
            String request = scanner.next();
            //创建DatagramPacket来储存数据 字节数组,数组长度,IP地址和端口号
            DatagramPacket requestpacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(this.IP),this.Port);
            //发送数据
            socket.send(requestpacket);
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
            //接收客户端处理后的消息
            socket.receive(responsePacket);
            //转化为 String 类型
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            //打印
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        EdpChoClient client = new EdpChoClient("127.0.0.1",1010);
        client.start();
    }
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。