java: 向服务器传输一个文件,从服务器获取文件大写

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

我想从客户端向服务器发送一个 .txt 文件并以大写形式返回。 但是这段代码 nothing.can 谁能告诉我这里出了什么问题..?

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

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();
        }
    }
}

CLIENT : 发送 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. 您的客户端没有向服务器发送 'stop reading' 信息(阅读下面的客户端代码)。这就是服务器在尝试读取客户端发送的数据时卡在 while 循环中的原因。这可能就是您尝试将数据直接发送回客户端的原因。关闭客户端的套接字输出以遵守套接字协定并正确释放套接字(请参阅 TCP/IP)。
  2. 给出的解决方案没有考虑到服务器在完成任务后应该保持运行。这样一来,服务器将无法同时为多个客户端提供服务。该服务器提供一次性服务,这是毫无意义的。要克服这个问题,您应该将所有内容都放在一个 while 循环中,并将每个新服务器进程绑定到一个新线程中(我让您这样做,这很令人高兴)。
  3. 服务器不考虑数据的整体大小,如果数据太大,它可能 运行 导致内存不足错误。您应该找到一种在实际实现中避免此问题的方法。
  4. 这两个程序都应该捕获异常并将其记录在某处,以便您可以了解任何错误。
  5. 编写服务器并不是那么简单。你通常应该用 headers 和其他类似的东西编写某种协议。为避免这种情况,请使用 objects,如 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,所以必须在发送请求后关闭socket输出。

  2. 你的复制循环是错误的。一般形式为:

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

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