Java 请求文件、发送文件(Client-server)

标签 java sockets networking connection-reset

我正在制作客户端-服务器。我已经知道服务器可以发送硬编码文件,但不能发送指定的客户端。我只需要发送文本文件。据我所知:客户端首先发送文件名,然后服务器发送它,没有什么复杂的,但我遇到了各种各样的错误,这段代码出现了连接重置/套接字关闭错误。主要问题是,没有太多时间研究网络。

如果能得到任何帮助,我将不胜感激。

编辑。 我找到了解决方法,关闭流会导致套接字关闭,这是为什么呢?这不应该发生,不是吗?

服务器端:

    InputStream sin=newCon.getInputStream();
    DataInputStream sdata=new DataInputStream(sin);
    location=sdata.readUTF();   
    //sdata.close();
    //sin.close();

File toSend=new File(location);
byte[] array=new byte[(int)toSend.length()];
FileInputStream fromFile=new FileInputStream(toSend);
BufferedInputStream toBuffer=new BufferedInputStream(fromFile);
toBuffer.read(array,0,array.length);

OutputStream out=newCon.getOutputStream(); //Socket-closed...
out.write(array,0,array.length);
out.flush();
toBuffer.close();
newCon.close();

客户端:

int bytesRead;
server=new Socket(host,port);

OutputStream sout=server.getOutputStream();
DataOutputStream sdata=new DataOutputStream(sout);
sdata.writeUTF(interestFile);
//sdata.close();
//sout.close();

InputStream in=server.getInputStream();     //socket closed..
OutputStream out=new FileOutputStream("data.txt");
byte[] buffer=new byte[1024];
while((bytesRead=in.read(buffer))!=-1)
{
    out.write(buffer,0,bytesRead);
}
out.close();
server.close();

最佳答案

尝试从服务器读取文件 block ,同时写入客户端输出流,而不是创建一个临时字节数组并将整个文件读入内存。如果请求的文件很大怎么办?还要在 finally block 中关闭服务器端的新套接字,这样即使抛出异常,套接字也会关闭。

服务器端:

    Socket newCon = ss.accept();
    FileInputStream is = null;
    OutputStream out = null;
    try {
        InputStream sin = newCon.getInputStream();
        DataInputStream sdata = new DataInputStream(sin);
        String location = sdata.readUTF();
        System.out.println("location=" + location);
        File toSend = new File(location);
        // TODO: validate file is safe to access here
        if (!toSend.exists()) {
            System.out.println("File does not exist");
            return;
        }
        is = new FileInputStream(toSend);
        out = newCon.getOutputStream();
        int bytesRead;
        byte[] buffer = new byte[4096];
        while ((bytesRead = is.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
        out.flush();
    } finally {
        if (out != null)
            try {
               out.close();
            } catch(IOException e) {
            }
        if (is != null)
            try {
               is.close();
            } catch(IOException e) {
            }
        newCon.close();
    }

如果您使用 Apache Common IOUtils库,那么您可以减少很多代码来将文件读/写到流中。这里 5 行缩减为一行。

org.apache.commons.io.IOUtils.copy(is, out);

请注意,使用通过绝对路径为远程客户端提供文件服务的服务器存在潜在危险,目标文件应限制在给定目录和/或一组文件类型中。不想向未经身份验证的客户端提供系统级文件。

关于Java 请求文件、发送文件(Client-server),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13844875/

相关文章:

java - 如何允许 Tomcat 上运行的应用程序访问网络目录?

docker - 在docker容器中启用ipv6转发

performance - VBA,文件系统对象,速度/优点/缺点

C# 和网络共享数据库

java - 在 JFileChooser 中仅显示 TSTA* 文件

java - Web服务——如何部署?

java - 如何为每个不同的 fragment 设置操作栏

c# - 如何从服务器中的客户端池中识别客户端 - 设计

linux - 为什么当参数 addr 没有分配 ip 地址时 connect() 连接主机本身

c - 套接字上的 select() 超时