Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)

简介: Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
客户端代码
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws Exception {
        //创建客户端对象,指定服务器端IP和端口号(host是服务器名称或IP地址,port是端口号)
        Socket client = new Socket("192.168.0.100", 8973);
        //使用socket中的方法创建输出流对象,向服务器端传送数据
        OutputStream outputStream = client.getOutputStream();

        //读取本地数据写进输出流中,传送给服务器端
        //创建输入流,关联数据源文件
        FileInputStream fileInputStream = new FileInputStream("client.txt");
        int len;
        byte[] bytes = new byte[8192];
        while ((len = fileInputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
        }

        //解决阻塞问题
        client.shutdownOutput();

        //创建输入流,获取服务器端传送回来的回执信息并且打印
        InputStream inputStream = client.getInputStream();
        while ((len = inputStream.read(bytes)) != -1){
            System.out.println(new String(bytes,0,len));
        }

        //关闭流
        client.close();
        outputStream.close();
        inputStream.close();
    }
}

服务器端
public class Server {
    public static void main(String[] args) throws Exception{
        //创建服务器端对象,指定服务器使用的端口号
        ServerSocket server = new ServerSocket(8973);
        //使用accpet方法接收客户端发送来的数据
        Socket accpet = server.accept();
        //使用socket中的方法创建输入流对象,获取客户端发送来的数据
        InputStream inputStream = accpet.getInputStream();

        //将客户端发送来的数据写入到服务器端的本地文件中
        //创建输出流,关联目的地文件
        FileOutputStream fileOutputStream = new FileOutputStream("server.txt");
        int len;
        byte[] bytes= new byte[8192];
        while((len = inputStream.read(bytes))!= -1){
            fileOutputStream.write(bytes,0,len);
        }

        //创建输出流,给客户端发送回执信息
        OutputStream outputStream = accpet.getOutputStream();
        outputStream.write("文件上传成功".getBytes());

        //关闭流
        //实际开发中,不会关闭服务器端的Socket对象
        accpet.close();
        outputStream.close();
    }
}

细节1:应该先启动服务器端,再启动客户端


细节2:client.shutdownOutput()方法是解决线程阻塞问题. 客户端while()循环中的结束条件为不等于-1,所以会发送结束符之前的信息.服务器端在接收数据进行while()循环读取的时候读取不到结束符,所以会一直运行陷入死循环.我们使用shutdownOutput()方法加入一个结束符,可以解决这个问题.

目录
相关文章
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
80 9
|
2月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
82 4
|
3月前
|
Java Linux
java读取linux服务器下某文档的内容
java读取linux服务器下某文档的内容
44 3
java读取linux服务器下某文档的内容
|
3月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
87 1
|
3月前
|
分布式计算 资源调度 Hadoop
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
100 4
|
3月前
|
Java Shell Maven
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
157 4
|
3月前
|
分布式计算 Java Hadoop
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
76 1
|
4月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
60 4
|
11天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
35 1
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
62 1