繁体   English   中英

java:将文件传输到服务器并以大写形式从服务器获取文件

[英]java: Transfer a file to the server and get the file from the server in upper case

我想将.txt文件从客户端发送到服务器,并以大写形式返回。 但是这段代码什么也没做。任何人都可以在这里说出什么问题吗?

服务器:从客户端获取文件并将其以大写形式发送回客户端。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

public class Assignment4_Server {

    public static void main(String[] args) throws IOException {
        byte[] bytearray = new byte[4096];
        try (ServerSocket ss = new ServerSocket(4444)) {
            Socket s = ss.accept();
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();
            int count;
            String data = null ;
            while((count = is.read(bytearray))>0){
                data = Arrays.toString(bytearray).toUpperCase();
                byte[] bytearrayout = data.getBytes();
                os.write(bytearrayout);
            }
            s.close();
        }
    }
}

客户端:将text.txt文件发送到服务器,大写转换后取回文件。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;


public class Assignment4_client {
    public static void main(String[] args) throws IOException {
        File file = new File("test.txt");
        byte[] bytearray = new byte[4096];
        Socket sc = new Socket("localhost",4444);
        //send file
        int countS , countR;
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        OutputStream os = sc.getOutputStream();
        while((countS = bis.read(bytearray))>0){
        os.write(bytearray);
        }
        //recieve file in uppercase from server
        InputStream is = sc.getInputStream();
        byte[] bytearray2 = new byte[4096];
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        while((countR = is.read(bytearray2))>0){
            bos.write(bytearray2);
        }
    }   
}

这是一个应该帮助您的代码。 但是在阅读之前,您应该知道发生了什么:

  1. 您的客户端没有向服务器发送“停止读取”信息(请阅读下面的客户端代码)。 这就是为什么服务器在尝试读取客户端发送的数据时陷入while循环的原因。 这可能就是您尝试将数据直接发送回客户端的原因。 关闭客户端的套接字输出以遵守Socket协定并正确释放套接字(请参阅TCP / IP)。
  2. 给出的解决方案未考虑服务器在完成其职责后应保持正常运行。 这样,该服务器将一次不能为一个以上的客户端提供服务。 该服务器提供一次性服务,这毫无意义。 为了克服这个问题,您应该将所有内容放入while循环中,并将每个新服务器进程绑定到一个新线程中(我很乐意为您服务)。
  3. 服务器没有考虑数据的整体大小,如果数据太重,服务器可能会遇到内存不足错误。 您应该找到一种在实际实现中避免此问题的方法。
  4. 两个程序都应捕获该异常并将其记录在某个地方,以便您可以知道任何错误。
  5. 编写服务器并不是那么简单。 通常,您应该使用标题和类似的东西编写某种协议。 为了避免这种情况,请使用诸如ObjectOutputStream和ObjectInputStream之类的对象,但它有一些限制,例如在Java世界中限制服务器。

客户

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class Client {


    public void send(File file)
    {
        Socket sc = null;
        try
        {
            byte[] bytearray = new byte[4096];
            sc = new Socket("localhost", 4444);

            // 1. Read the file, send its content, close it. 
            int count;
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            OutputStream os = sc.getOutputStream();

            while((count = bis.read(bytearray))>0)
            {
                os.write(bytearray);
            }
            fis.close();
            sc.shutdownOutput();

            // 2. Delete old file, receive data, write it to new File.
            InputStream is = sc.getInputStream();
            bytearray = new byte[4096];
            // Eventually do what you want with the file: new one, append, etc.
            file.delete();
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            count = 0;
            while((count = is.read(bytearray)) > 0)
            {
                bos.write(bytearray, 0, count);
            }
            fos.close();
            bos.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (sc != null)
            {
                try
                {
                    sc.close();
                } catch (IOException e) {}
            }
        }
    }
}

服务器

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server
{
    Server()
    {
        Socket s = null;
        byte[] bytearray = new byte[4096];
        try (ServerSocket ss = new ServerSocket(4444))
        {
            s = ss.accept();
            InputStream is = s.getInputStream();

            // 1. Recieve data and put it to UpperCase.
            String data = "";
            int count;
            while((count = is.read(bytearray)) > 0)
            {
                data += new String(bytearray, 0, count);
            }
            data = data.toUpperCase();
            System.out.println(data);

            // 2. Send back data.
            OutputStream os = s.getOutputStream();
            os.write(data.getBytes());
            os.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

测试程序

这应该可以帮助您在IDE的同一项目中测试这两个程序。

import java.io.File;

public class Test
{
    public static void main(String[] args)
    {
        Client c = new Client();
        (new Thread()
        {
            public void run()
            {
                Server s = new Server();
            }
        }).start();
        c.send(new File("test.txt"));
    }
}

这里有两件事很简单。

  1. 服务器一直在套接字上读取直到流结束,套接字必须用于回复。 因此,客户端在发送提供EOS的请求后无法关闭它,因此它必须在发送请求后关闭套接字以输出。

  2. 您的复制循环是错误的。 通用形式为:

     while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); } 

    您在写入时会忽略读取计数,因此将在流的末尾或在read()未填充buffer任何其他时间写入垃圾,这可能是任何时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM