互联网编程之基于 TCP 的单线程文件收发程序(CS架构)

2023-11-15

目录

需求

服务端实现

客户端实现

测试


需求

可试着根据java编程课所学到的java socket编程技术,尝试编写一个基于 TCP 的单线程文件收发程序,需满足:

服务端程序预先定义好需要发送的文件并等待客户端的连接。

客户端连接成功后,服务端将文件发送给客户端,客户端将文件保存到本地。

需要在同一个 TCP 连接内发送多个文件,不限制文件的类型和大小(操作系统支持的前提下)。

服务端实现

服务端Service实现

首先使用在端口6666创建一个ServerSocket类对象,使用accept方法监听6666端口的入站连接,如图12所示。

图12

创建DataOutputStream输出流对象,将文件的数量、各个文件的名字以及各个文件的大小写入输出流,如图13所示。

图13

创建BufferOutputStream输出流对象,将文件以字节流的方式发送出去,如图14所示。

图14

Java完整代码 

使用Socket建立了一个服务器,并向连接上该服务器的客户端发送特定文件夹中的文件信息和文件内容。

首先,通过创建ServerSocket对象并指定端口号6666,该服务器将在该端口上监听客户端的连接请求。

接下来,通过调用serverSocket.accept()方法,服务器将等待客户端的连接,并一旦有客户端连接上,就会返回一个表示客户端连接的Socket对象。

然后,定义了一个File对象file,指定了要发送文件的文件夹路径。

通过调用file.listFiles()方法,获取文件夹中的所有文件,并保存在一个File数组files中。

接下来,通过创建DataOutputStream对象data,并使用socket的输出流进行初始化。之后,通过data.writeInt(files.length)将文件数量写入输出流,告诉客户端接下来要传送的文件数量。

然后,通过循环遍历files数组,依次将每个文件名和文件长度写入输出流,使用data.writeUTF(files[i].getName())data.writeLong(files[i].length())完成。

接下来,创建了一个BufferedOutputStream对象output,利用socket的输出流进行初始化。然后,再次循环遍历files数组,对每一个文件创建一个BufferedInputStream对象input,读取文件的内容,并将内容通过output写入到socket的输出流中,实现文件的传输。

最后,关闭output、socket和serverSocket,释放相关资源。

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Service {
    public static void main(String[] args)throws Exception {
        ServerSocket serverSocket=new ServerSocket(6666);
        Socket socket=serverSocket.accept();
        File file=new File("C:\\Users\\Yezi\\Desktop\\互联网编程\\实验1\\Service");
        File[] files=file.listFiles();
        DataOutputStream data=new DataOutputStream(socket.getOutputStream());
        data.writeInt(files.length);
        for(int i=0;i<files.length;i++){
            data.writeUTF(files[i].getName());
            data.writeLong(files[i].length());
        }
        BufferedOutputStream output=new BufferedOutputStream(socket.getOutputStream());
        for(int i=0;i<files.length;i++){
            BufferedInputStream input=new BufferedInputStream(new FileInputStream("C:\\Users\\Yezi\\Desktop\\互联网编程\\实验1\\Service\\"+files[i].getName()));
            int one=input.read();
            while(one!=-1){
                output.write(one);
                one=input.read();
            }
        }
        output.close();
        socket.close();
        serverSocket.close();
    }
}

客户端实现

客户端Client实现

首先创建套接字并将其连接到本地IP地址的6666端口,创建DataInputStream输入流对象,准备接受字节流,如图15所示。

图15

接收文件数量、各个文件的名字以及各个文件的大小,如图16所示。

图16

创建BufferInputStream输入流对象,以字节流的方法接收各个文件,并保存在本地,如图17所示。

图17

Java完整代码 

通过Socket连接到指定的服务器,并接收服务器发送过来的文件信息和文件内容,保存到本地。

首先,通过创建Socket对象并指定服务器的IP地址(InetAddress.getLocalHost())和端口号6666,客户端将连接到该地址上的服务器。

接下来,创建DataInputStream对象data,并使用socket的输入流进行初始化。然后,通过data.readInt()读取服务器发送过来的文件数量。

接着,定义了两个数组fileName和fileLength,用于保存每个文件的文件名和文件长度。

通过循环遍历文件数量fileNumber,分别从输入流中读取文件名和文件长度,并将其保存在对应的数组中,使用fileName[i]=data.readUTF()fileLength[i]=data.readLong()完成。

然后,创建了一个BufferedInputStream对象input,利用socket的输入流进行初始化。然后,再次循环遍历文件数量fileNumber,在每一轮循环中,先创建一个BufferedOutputStream对象output,使用FileOutputStream将其绑定到指定路径的文件上。

通过循环读取input中的每一个字节,并将其写入到output中,实现文件的接收和保存。

最后,关闭output、socket的输出流(通过socket.shutdownOutput())以及socket,释放相关资源。

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
    public static void main(String[] args)throws Exception {
        Socket socket=new Socket(InetAddress.getLocalHost(),6666);
        DataInputStream data=new DataInputStream(socket.getInputStream());
        int fileNumber=data.readInt();
        String[] fileName=new String[fileNumber];
        long[] fileLength=new long[fileNumber];
        for(int i=0;i<fileNumber;i++){
            fileName[i]=data.readUTF();
            fileLength[i]=data.readLong();
        }
        BufferedInputStream input=new BufferedInputStream(socket.getInputStream());
        for(int i=0;i<fileNumber;i++){
            BufferedOutputStream output=new BufferedOutputStream(new FileOutputStream("C:\\Users\\Yezi\\Desktop\\互联网编程\\实验1\\Client\\"+fileName[i]));
            for(long j=0;j<fileLength[i];j++){
                int one=input.read();
                output.write(one);
            }
            output.close();
        }
        socket.shutdownOutput();
        socket.close();
    }
}

测试

准备好多个文件,包括不同类型的图片、excel表格文件、ppt文件,准备发送,如图18所示。

图18

运行Service程序和Client程序,在Client文件查看测试结果,所有文件成功传送,测试成功,如图19所示。

图19

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

互联网编程之基于 TCP 的单线程文件收发程序(CS架构) 的相关文章

随机推荐

  • 管理“项目”之人际关系篇

    项目管理里的人际关系 也是令人头疼且最重要的 管的好 众人拾柴 火焰高 管的不好 眼看他起高楼 眼看他楼塌了 文章目录 前言 一 项目关系人管理 1 项目创立一定要获得关系人尤其主要关系人 或市场 的认可 2 识别相关人员 识别关系人 3
  • Cesium:入门教程(一)之 Hello World

    简介 Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎 Cesium支持3D 2D 2 5D形式的地图展示 它提供了基于JavaScript语言的开发包 方便用户快速搭建一款零插件的虚拟地球Web应用 并在性能
  • Qt源码分析之信号和槽机制

    原文在这里 http blog csdn net oowgsoo article details 1529411 Qt的信号和槽机制是Qt的一大特点 实际上这是和MFC中的消息映射机制相似的东西 要完成的事情也差不多 就是发送一个消息然后让
  • 电脑系统更新完后,计算机管理服务中找不到mysql的服务

    问题场景 电脑系统更新完 重启电脑 发现在电脑 计算机管理服务中找不到mysql的服务 问题描述 重启后 计算机管理如图 解决方案 使用Windows Powershell 管理员模式 进入到mysql安装目录bin 然后执行 mysqld
  • Unity游戏开发-Assetbundle打包

    本篇主要是分享unity Assetbundle的打包处理 目录 打包接口 整体设计 打包AssetBundle 压缩资源到StreamingAssets 输出资源清单文件 清单文件结构 AssetFile AssetVersion 处理
  • Codeforces-1454E Number of Simple Paths(基环树-思维)

    题目大意 给你n个点 n条边 求图中简单路径的个数 题目思路 n个点n条边 那么图中一定有一个环 拿这个图来讲 我们将两点间的关系分为4种 1 两点都在环上 简单路径的个数为2 例如2与5 2 一个点在环上一个点不在环上 简单路径个数为2
  • 魔兽世界(WOW)诺莫瑞根卡片任务链ASCII码解码(python)

    运行环境 python 3 9 翻译结果 A机器上的编码 Tell your friends to play WoW 白色卡片上的编码 Thrall and Jaina sitting in a tree K I S S I N G A机器
  • 使用openssl中函数MD5_Init、MD5_Update、MD5_Final出现LNK2019 unresolved externalsymbol错误解决方法

    添加对应的静态链接库 以vs2013为例 PROJECT gt Properties gt Linker gt Additional Dependencies 添加libeay32 lib 先确认库的搜索路径中libeay32 lib
  • LVGL8.1笔记3--运行demo(2022-0611)

    LVGL8 1笔记3 运行demo 2022 0611 文章目录 LVGL8 1笔记3 运行demo 2022 0611 toc 前言 一 移植前准备 二 lv demo简介 三 开始移植demo 1 首先下载demo 如果用的不是LVGL
  • sdc基本概念-set_clock_groups

    set clock groups 指定clock groups 之间的关系是mutually exclusive or asynchronous 这些clock 间的timing path 是不做分析的 status set clock g
  • cass等距离等分线段的命令键_cad等分快捷键(cad等分线段快捷键命令)

    CAD中等分线段分为两种 定数等分和定距等分 1 定数等分 命令是DIVIDE 快捷键是DIV 2 定距等分 命令是MEASURE 快捷键是ME 以线段定数等分为例 1 命令为DIV 以CAD2010操作为例 1 打开CAD的软件 如图所示
  • LeetCode 99. 恢复二叉搜索树

    题目链接 https leetcode cn com problems recover binary search tree 思路如下 如下图所示 正常情况下中序遍历的结果是升序的 11 17 18 22 28 37 42 44 62 如下
  • Hive设置本地模式

    set hive exec mode local auto true
  • 使用EasyPOI导出Excel表格(含多sheet导出以及一对多导出)

    一 前言 官方Api文档地址 http doc wupaas com docs easypoi easypoi 1c0u4mo8p4ro8 常用注解介绍 注解介绍 easypoi起因就是Excel的导入导出 最初的模板是实体和Excel的对
  • SqlServer 关于 datetime 的更新引发的思考

    今天在测试更新 SqlServer 表的 datetime 字段时 突然发现并没有更新成功 同时也没有报错 感觉十分诧异 因此仔细排查了一下 终于发现是和字段本身的精度有关 现象 假设我们现在有一张 SqlServer 表 basic in
  • LC-3 机器语言 指令集

    目录 碎碎念念 LC 3指令 运算类指令 ADD addition AND Bit wise logical AND NOT Bit wise complement 数据搬移类指令 LD load ST store LDI load ind
  • FPN网络结构+源码讲解

    YOLOF前传 特征金字塔 FPN 前言 这几天在读CVPR2021的中稿论文YOLOF You Only Look One level Feature 文章回顾了单阶段的特征金字塔网络 FPN 指出FPN的成功的原因在于它对目标检测中优化
  • c++ map用法 入门必看 超详细

    1 map的作用 可以实现各种类型的映射 可以用数组来类比 都是由下标和值组成 但数组用法很局限 下标不能是负数 而且开数组需要消耗太多的内存 开到10 7就内存超限了 因此 很多时候都用高级的map类或vector类来代替数组 其里面的成
  • “对象创建”模式——抽象工厂

    动机 在软件系统中 经常面临着 一系列相互依赖的对象 的创建工作 同时由于需求的变化 往往存在更多系列对象的创建对象 如何应对这种变化 如何绕过常规的对象创建方法 new 提供一种 封装机制 来避免客户程序和这种 多系列具体对象创建工作 的
  • 互联网编程之基于 TCP 的单线程文件收发程序(CS架构)

    目录 需求 服务端实现 客户端实现 测试 需求 可试着根据java编程课所学到的java socket编程技术 尝试编写一个基于 TCP 的单线程文件收发程序 需满足 服务端程序预先定义好需要发送的文件并等待客户端的连接 客户端连接成功后