Java通过 Socket 实现 TCP服务端

yizhihongxing

下面开始对“Java通过Socket实现TCP服务端”的完整攻略进行详细讲解。

概述

在Java中,可以通过Socket来实现TCP的通信。作为服务端,需要启动一个监听线程来接受客户端的连接请求,并创建一个接受处理线程来处理客户端发送的数据。下面将从以下几个方面来讲解如何通过Socket实现TCP服务端:

  1. 启动服务端
  2. 监听客户端连接请求
  3. 处理客户端发送的数据
  4. 关闭服务端

启动服务端

在Java中启动服务端,需要创建一个ServerSocket对象,并设置需要监听的端口号。以下是示例代码:

int port = 8080;
try {
    ServerSocket serverSocket = new ServerSocket(port);
    System.out.println("服务端已启动,监听端口:" + port);
} catch (IOException e) {
    e.printStackTrace();
}

监听客户端连接请求

启动服务端后,需要创建一个线程来监听客户端的连接请求。对于每个连接请求,都需要创建一个新的Socket对象来与客户端进行通信。以下是示例代码:

while (true) {
    try {
        Socket clientSocket = serverSocket.accept();
        System.out.println("客户端连接成功,客户端地址:" + clientSocket.getInetAddress() + ",客户端端口:" + clientSocket.getPort());
        // 处理客户端发送的数据
        // ...
    } catch (IOException e) {
        e.printStackTrace();
    }
}

在循环中调用ServerSocket.accept()方法,等待客户端连接请求。如果客户端发起连接请求,则该方法将返回一个新的Socket对象,程序将创建一个新线程来处理该连接。

处理客户端发送的数据

在接受到客户端连接后,需要通过InputStream读取客户端发送的数据,并通过OutputStream将处理结果返回给客户端。以下是示例代码:

try {
    InputStream inputStream = clientSocket.getInputStream();
    OutputStream outputStream = clientSocket.getOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = inputStream.read(buffer)) > 0) {
        String receivedData = new String(buffer, 0, len);
        System.out.println("接收到客户端数据:" + receivedData);
        // 处理客户端发送的数据
        String responseData = "收到您发来的数据:" + receivedData;
        outputStream.write(responseData.getBytes());
        outputStream.flush();
        System.out.println("响应客户端数据:" + responseData);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        clientSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

在处理数据的过程中,需要通过InputStream读取客户端发送的数据。可以先创建一个byte数组作为缓冲区,通过InputStream.read()方法读取客户端发送的数据。读取到数据之后,可以将byte数组转换为字符串,并进行处理。

处理完客户端发送的数据之后,需要通过OutputStream将处理结果返回给客户端。可以通过OutputStream.write()方法将处理结果转换为byte数组,再通过OutputStream.flush()方法将数据发送给客户端。

处理完客户端数据后,需要关闭与客户端的Socket连接。

关闭服务端

在服务端不需要接受客户端连接请求时,需要关闭ServerSocket对象。以下是示例代码:

try {
    serverSocket.close();
    System.out.println("服务端已关闭");
} catch (IOException e) {
    e.printStackTrace();
}

示例

下面给出两个示例:

示例1

该示例实现了一个简单的文件上传服务器,客户端向服务端上传文件,服务端将文件保存到指定目录中。以下是服务端代码:

int port = 8080;
String savePath = "D:/upload/";
int bufferSize = 1024;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("服务端已启动,监听端口:" + port);
while (true) {
    try {
        Socket clientSocket = serverSocket.accept();
        System.out.println("客户端连接成功,客户端地址:" + clientSocket.getInetAddress() + ",客户端端口:" + clientSocket.getPort());
        // 处理客户端发送的数据
        InputStream inputStream = clientSocket.getInputStream();
        byte[] buffer = new byte[bufferSize];
        int len;
        String fileName = null;
        int fileLength = 0;
        // 读取文件名
        if ((len = inputStream.read(buffer)) > 0) {
            fileName = new String(buffer, 0, len);
        }
        // 读取文件长度
        if ((len = inputStream.read(buffer)) > 0) {
            fileLength = Integer.parseInt(new String(buffer, 0, len));
        }
        FileOutputStream fileOutputStream = new FileOutputStream(new File(savePath + fileName));
        // 读取文件内容
        int count = 0;
        while ((len = inputStream.read(buffer)) > 0) {
            fileOutputStream.write(buffer, 0, len);
            count += len;
            if (count == fileLength) {
                break;
            }
        }
        fileOutputStream.close();
        // 响应客户端
        OutputStream outputStream = clientSocket.getOutputStream();
        String responseData = "文件上传成功";
        outputStream.write(responseData.getBytes());
        outputStream.flush();
        System.out.println("响应客户端数据:" + responseData);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

以下是客户端代码:

String serverIP = "localhost";
int port = 8080;
String filePath = "D:/test.jpg";
int bufferSize = 1024;
Socket clientSocket = new Socket(serverIP, port);
InputStream inputStream = new FileInputStream(new File(filePath));
OutputStream outputStream = clientSocket.getOutputStream();
byte[] buffer = new byte[bufferSize];
int len;
// 发送文件名
String fileName = new File(filePath).getName();
outputStream.write(fileName.getBytes());
outputStream.flush();
// 发送文件长度
int fileLength = inputStream.available();
String fileLengthStr = String.valueOf(fileLength);
outputStream.write(fileLengthStr.getBytes());
outputStream.flush();
// 发送文件内容
while ((len = inputStream.read(buffer)) > 0) {
    outputStream.write(buffer, 0, len);
    outputStream.flush();
}
// 接收响应
buffer = new byte[bufferSize];
if ((len = clientSocket.getInputStream().read(buffer)) > 0) {
    String responseData = new String(buffer, 0, len);
    System.out.println("接收到服务端响应:" + responseData);
}
inputStream.close();
outputStream.close();
clientSocket.close();

示例2

该示例通过Socket实现了多线程的服务端。以下是服务端代码:

int port = 8080;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("服务端已启动,监听端口:" + port);
while (true) {
    try {
        Socket clientSocket = serverSocket.accept();
        System.out.println("客户端连接成功,客户端地址:" + clientSocket.getInetAddress() + ",客户端端口:" + clientSocket.getPort());
        new SocketThread(clientSocket).start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

以下是SocketThread类的代码:

public class SocketThread extends Thread {

    private final Socket clientSocket;

    public SocketThread(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try {
            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > 0) {
                String receivedData = new String(buffer, 0, len);
                System.out.println("接收到客户端数据:" + receivedData);
                // 处理客户端发送的数据
                String responseData = "收到您发来的数据:" + receivedData;
                outputStream.write(responseData.getBytes());
                outputStream.flush();
                System.out.println("响应客户端数据:" + responseData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

以上就是用Java通过Socket实现TCP服务端的完整攻略,包括启动服务端、监听客户端连接请求、处理客户端发送的数据和关闭服务端四个方面,并提供了两个示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java通过 Socket 实现 TCP服务端 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 尼尔机械纪元加载时间长怎么解决 游戏loading时间太长解决方法

    尼尔机械纪元加载时间长解决方法 问题分析 尼尔机械纪元是一款高度画质的游戏,加载时间长是较为普遍的问题。为解决此问题,我们需要从以下几个方面入手。 游戏所处设备的硬件配置。 游戏安装路径的选择。 优化游戏本身的设置。 解决方案 方案一:升级硬件 游戏需要配置高端显卡、大容量内存等硬件,所以升级硬件是解决加载时间长问题的很有效的方法。以下是升级硬件的推荐方案:…

    other 2023年6月25日
    00
  • iso14229简介转载

    ISO14229简介转载 ISO14229是一项国际标准,为汽车电子系统中的诊断通信定义了统一的协议和服务。其通信协议基于CAN总线,并支持多种传输层协议,如ISO9113等。 ISO14229协议定义了一些诊断服务和协议,如诊断会话控制服务,ECU诊断服务和ECU编程/配置服务等。这些服务为车辆制造商和维修机构提供了一种标准化的方式来操作汽车电子系统,并且…

    其他 2023年3月28日
    00
  • Spring导入properties配置文件代码示例

    请看以下 Spring 导入 properties 配置文件的完整攻略: 1. 创建 properties 配置文件 首先,我们需要在项目中创建一个 properties 文件,比如 config.properties,用于存储配置信息。在文件中添加需要配置的属性,如下所示: jdbc.driver=com.mysql.jdbc.Driver jdbc.ur…

    other 2023年6月25日
    00
  • 解析linux或android添加文件系统的属性接口的方法

    下面是详细讲解“解析linux或android添加文件系统的属性接口的方法”的攻略。 什么是文件系统属性接口 在Linux或Android中,每个文件或目录都有一些属性,如权限、所有者、大小等等。这些属性可以通过文件系统属性接口来读取或修改。 添加文件系统属性接口 如果您想要为您的文件系统添加自定义属性,您可以遵循以下步骤: 步骤1:实现文件系统操作 添加自…

    other 2023年6月26日
    00
  • 如何通过apt-get获得安装包的源码

    如何通过apt-get获得安装包的源码 在Linux系统中,使用APT (Advanced Package Tool)来安装软件包是常见的做法。通常我们只需要使用apt-get命令即可快速安装需要的软件包。然而在某些情况下,我们需要获取软件包的源码来自行编译或者进行其他自定义操作。下面将介绍如何通过apt-get命令获得安装包的源码。 步骤 首先,我们需要添…

    其他 2023年3月28日
    00
  • thinkPHP模型初始化实例分析

    当我们在ThinkPHP中进行数据库操作时,通常需要定义一个模型来进行数据库的操作。在模型进行操作之前,需要初始化一个包含数据库配置等基础信息的实例。本文将会详细讲解ThinkPHP模型初始化实例的构建方式,方便开发者在进行数据库操作时更加容易上手。 第一步:创建模型 在使用ThinkPHP模型进行数据库操作前,需要先创建一个模型。可以通过命令行工具或者手动…

    other 2023年6月20日
    00
  • MySQL 启动成功但未监听端口的解决方法

    下面是“MySQL 启动成功但未监听端口的解决方法”的完整攻略: 问题描述 在启动 MySQL 时,提示成功启动,但是在无法连接 MySQL 时,发现 MySQL 并没有监听端口。 原因分析 这个问题的原因可能是因为 MySQL 服务没有正确启动。但是启动过程中没有报错,具体原因需要进一步排查。 解决方法 以下是解决该问题的几种方法: 方法一:检查 MySQ…

    other 2023年6月27日
    00
  • HTML+CSS+JavaScript通过嵌套ul li实现简单的二级菜单

    当使用HTML、CSS和JavaScript通过嵌套ul和li来实现简单的二级菜单时,可以按照以下步骤进行操作: 创建HTML结构:首先,在HTML文件中创建一个ul元素,作为一级菜单的容器。在该ul元素中,创建多个li元素,每个li元素代表一个一级菜单项。对于每个一级菜单项,可以在其下方创建一个嵌套的ul元素,作为二级菜单的容器。在二级菜单的ul元素中,创…

    other 2023年7月28日
    00
合作推广
合作推广
分享本页
返回顶部