简绍

Socket" 在计算机网络编程中通常指的是用于在网络中的两个程序之间建立通信连接的一种机制。Socket 可以让你的应用程序通过网络发送和接收数据。它提供了一种双向通信协议,使得客户端和服务器端可以相互通信。

Socket 的基本概念
  • 客户端:通常发起连接请求的程序。
  • 服务器:等待并接受连接请求的程序。
根据传输层协议的不同,Socket 主要有两种类型:
  • TCP Socket:基于 TCP(传输控制协议)的 Socket,提供面向连接的服务,保证数据的可靠传输。
  • UDP Socket:基于 UDP(用户数据报协议)的 Socket,不保证数据的顺序性和可靠性,但传输速度较快。
TCP

TCP (Transmission Control Protocol) 是一种面向连接的、可靠的传输层协议,它提供了数据包的排序、流量控制和错误检测机制。TCP 通常用于需要高度可靠性的网络应用中,比如 Web 浏览、电子邮件、文件传输等。

TCP 的特点

  • 面向连接:在数据传输之前,必须先建立连接,数据传输完成后释放连接。
  • 可靠传输:通过序列号和确认应答机制来确保数据的可靠传输。
  • 流量控制:通过滑动窗口机制来避免接收方来不及处理发送方发送过来的数据。
  • 拥塞控制:通过调整发送速率来避免网络拥塞。
TCP服务端

以下是一个简单的服务器端示例,它使用 ServerSocket 监听特定端口上的连接请求。

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

public class SimpleServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(6013); // 选择一个端口
            System.out.println("Server started on port " + serverSocket.getLocalPort());

            while (true) {
                Socket clientSocket = serverSocket.accept(); // 等待客户端连接
                new ClientHandler(clientSocket).start();
            }
        } finally {
            if (serverSocket != null)
                serverSocket.close();
        }
    }
}

class ClientHandler extends Thread {
    private Socket clientSocket;

    public ClientHandler(Socket socket) {
        this.clientSocket = socket;
    }

    public void run() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println("Received: " + inputLine);
                out.println("Echo: " + inputLine);
            }

            in.close();
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("Error handling client: " + e.getMessage());
        }
    }
}
TCP 客户端

Socket 连接到上面创建的服务器。

public class SimpleClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 6013); // 连接到服务器
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("Connected to server at " + socket.getRemoteSocketAddress());
        String userInput;
        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);
            System.out.println("Received from server: " + in.readLine());
        }

        out.close();
        in.close();
        socket.close();
    }
}
服务器端:

创建一个 ServerSocket 并绑定到一个端口上。
无限循环等待客户端连接。
对每个连接创建一个新的线程来处理客户端的请求。
读取客户端发送的数据,并将其回发给客户端。
关闭连接。

客户端:

创建一个 Socket 并连接到服务器。
从标准输入读取用户输入,并发送给服务器。
接收服务器响应的数据,并打印出来。
关闭连接。

确保服务器和客户端的端口号一致。
服务器端应该先启动,以便客户端可以连接到它。
在实际应用中,你可能需要处理异常情况,比如断开连接或超时。

UDP

UDP (User Datagram Protocol) 是一种无连接的、不可靠的传输层协议,与 TCP (Transmission Control Protocol) 不同,它不提供数据包的排序、流量控制和确认机制。这意味着 UDP 比 TCP 更加轻量级,适用于对实时性要求较高的应用,如视频会议、在线游戏等。

UDP 的特点

  • 无连接:发送数据前无需建立连接。
  • 不可靠:不保证数据包的顺序到达,也不保证数据包一定能够到达目的地。
  • 速度快:由于不需要建立连接,因此数据传输速度较快。
  • 广播和多播支持:UDP 支持广播和多播地址,非常适合一对多的通信场景。
Java 中的 UDP 编程

在 Java 中,使用 DatagramSocket 和 DatagramPacket 类来进行 UDP 编程。下面是一个简单的 UDP 服务器和客户端的示例。

UDP 服务器端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPServer {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(6013); // 监听端口
        byte[] receiveData = new byte[256];

        while (true) {
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            socket.receive(receivePacket); // 接收数据

            String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("RECEIVED: " + sentence);

            // 回复客户端
            InetAddress IPAddress = receivePacket.getAddress();
            int port = receivePacket.getPort();
            byte[] sendData = ("Echo: " + sentence).getBytes();
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
            socket.send(sendPacket);
        }
    }
}
UDP 客户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClient {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        byte[] sendData = "Hello UDP Server".getBytes();
        InetAddress IPAddress = InetAddress.getByName("localhost"); // 服务器地址
        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 6013); // 服务器端口

        socket.send(sendPacket); // 发送数据

        byte[] receiveData = new byte[256];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        socket.receive(receivePacket); // 接收数据

        String modifiedSentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
        System.out.println("RECEIVED: " + modifiedSentence);

        socket.close();
    }
}
服务器端:

创建一个 DatagramSocket 并绑定到一个端口上。
无限循环接收来自客户端的数据包。
解析数据包的内容,并打印出来。
创建一个新的数据包,将数据回发给客户端。

客户端:

创建一个 DatagramSocket。
创建一个数据包,包含要发送的数据和服务器的信息。
发送数据包。
接收服务器响应的数据包,并解析打印。
关闭 DatagramSocket。

UDP 不保证数据包的到达顺序或丢失情况,因此在设计应用程序时需要考虑这些问题。
如果你的应用需要保证数据包的顺序或完整性,可能需要自己实现一些机制,例如序列号、重传机制等。
对于广播或多播通信,可以使用特定的广播或多播地址。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部