java - 使用java套接字从客户端向服务器发送文本文件

标签 java file sockets client-server

这是一个作业。

我正在寻找一些关于我在这里哪里出错的建议。我的目标是从文件中读取文本,将其发送到服务器并将该文本写入新文件。

问题是我不确定如何去做,我看过很多例子,但没有一个有多大帮助。

按原样解释程序。将要求用户输入与该代码的 if 语句相关的代码。我想关注的是代码 200,它是将文件上传到服务器的代码。

当我运行代码时,出现以下错误。有人可以向我解释我哪里出错了,我将不胜感激。

    Connection request made
Enter Code: 100 = Login, 200 = Upload, 400 = Logout:
200
java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at MyStreamSocket.receiveMessage(MyStreamSocket.java:50)
        at EchoClientHelper2.getEcho(EchoClientHelper2.java:34)
        at EchoClient2.main(EchoClient2.java:99)

服务器上的这个错误:

    Waiting for a connection.
connection accepted
message received: 200
java.net.SocketException: Socket is not connected
        at java.net.Socket.getInputStream(Unknown Source)
        at EchoServer2.main(EchoServer2.java:71)

最佳答案

您的 MyStreamSocket 类不需要扩展 Socket。神秘的错误信息是因为 MyStreamSocket 代表的 Socket 从未连接到任何东西。由其 socket 成员引用的 Socket 是已连接的。因此,当您从 MyStreamSocket 获取输入流时,它确实没有连接。这会导致错误,这意味着客户端会关闭。这会导致套接字关闭,服务器会及时报告

BufferedReader 的使用会给您带来麻烦。它总是尽可能多地读取其缓冲区,因此在文件传输开始时,它将读取“200”消息,然后是发送文件的前几 Kb,这些文件将被解析为字符数据。结果将是一大堆错误。

我建议您现在摆脱 BufferedReader,改用 DataInputStream 和 DataOutputStream。您可以使用 writeUTF 和 readUTF 方法发送文本命令。要发送文件,我建议使用简单的 block 编码。

如果我给你代码,这可能是最简单的。

首先是您的客户类。

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

public class EchoClient2 {

    public static void main(String[] args) {
        InputStreamReader is = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(is);

        File file = new File("C:\\MyFile.txt");

        try {
            System.out.println("Welcome to the Echo client.\n"
                    + "What is the name of the server host?");
            String hostName = br.readLine();
            if( hostName.length() == 0 ) // if user did not enter a name
                hostName = "localhost"; // use the default host name
            System.out.println("What is the port number of the server host?");
            String portNum = br.readLine();
            if( portNum.length() == 0 ) portNum = "7"; // default port number
            MyStreamSocket socket = new MyStreamSocket(
                    InetAddress.getByName(hostName), Integer.parseInt(portNum));
            boolean done = false;
            String echo;
            while( !done ) {

                System.out.println("Enter Code: 100 = Login, 200 = Upload, 400 = Logout: ");
                String message = br.readLine();
                boolean messageOK = false;

                if( message.equals("100") ) {
                    messageOK = true;
                    System.out.println("Enter T-Number: (Use Uppercase 'T')");
                    String login = br.readLine();
                    if( login.charAt(0) == 'T' ) {
                        System.out.println("Login Worked fantastically");
                    } else {
                        System.out.println("Login Failed");
                    }
                    socket.sendMessage("100");
                }

                if( message.equals("200") ) {
                    messageOK = true;
                    socket.sendMessage("200");
                    socket.sendFile(file);
                }
                if( (message.trim()).equals("400") ) {
                    messageOK = true;
                    System.out.println("Logged Out");
                    done = true;
                    socket.sendMessage("400");
                    socket.close();
                    break;
                }

                if( ! messageOK ) {
                    System.out.println("Invalid input");
                    continue;
                }

                // get reply from server
                echo = socket.receiveMessage();
                System.out.println(echo);
            } // end while
        } // end try
        catch (Exception ex) {
            ex.printStackTrace();
        } // end catch
    } // end main
} // end class

然后是你的服务器类:

import java.io.*;
import java.net.*;

public class EchoServer2 {
    static final String loginMessage = "Logged In";

    static final String logoutMessage = "Logged Out";


    public static void main(String[] args) {
        int serverPort = 7; // default port
        String message;

        if( args.length == 1 ) serverPort = Integer.parseInt(args[0]);
        try {
            // instantiates a stream socket for accepting
            // connections
            ServerSocket myConnectionSocket = new ServerSocket(serverPort);
            /**/System.out.println("Daytime server ready.");
            while( true ) { // forever loop
                // wait to accept a connection
                /**/System.out.println("Waiting for a connection.");
                MyStreamSocket myDataSocket = new MyStreamSocket(
                        myConnectionSocket.accept());
                /**/System.out.println("connection accepted");
                boolean done = false;
                while( !done ) {
                    message = myDataSocket.receiveMessage();

                    /**/System.out.println("message received: " + message);

                    if( (message.trim()).equals("400") ) {
                        // Session over; close the data socket.
                        myDataSocket.sendMessage(logoutMessage);
                        myDataSocket.close();
                        done = true;
                    } // end if

                    if( (message.trim()).equals("100") ) {
                        // Login
                        /**/myDataSocket.sendMessage(loginMessage);
                    } // end if

                    if( (message.trim()).equals("200") ) {

                        File outFile = new File("C:\\OutFileServer.txt");
                        myDataSocket.receiveFile(outFile);
                        myDataSocket.sendMessage("File received "+outFile.length()+" bytes");
                    }

                } // end while !done
            } // end while forever
        } // end try
        catch (Exception ex) {
            ex.printStackTrace();
        }
    } // end main
} // end class

然后是 StreamSocket 类:

public class MyStreamSocket {
    private Socket socket;

    private DataInputStream input;

    private DataOutputStream output;


    MyStreamSocket(InetAddress acceptorHost, int acceptorPort)
            throws SocketException, IOException {
        socket = new Socket(acceptorHost, acceptorPort);
        setStreams();
    }


    MyStreamSocket(Socket socket) throws IOException {
        this.socket = socket;
        setStreams();
    }


    private void setStreams() throws IOException {
        // get an input stream for reading from the data socket
        input = new DataInputStream(socket.getInputStream());
        output = new DataOutputStream(socket.getOutputStream());
    }


    public void sendMessage(String message) throws IOException {
        output.writeUTF(message);
        output.flush();
    } // end sendMessage


    public String receiveMessage() throws IOException {
        String message = input.readUTF();
        return message;
    } // end receiveMessage


    public void close() throws IOException {
        socket.close();
    }


    public void sendFile(File file) throws IOException {
        FileInputStream fileIn = new FileInputStream(file);
        byte[] buf = new byte[Short.MAX_VALUE];
        int bytesRead;        
        while( (bytesRead = fileIn.read(buf)) != -1 ) {
            output.writeShort(bytesRead);
            output.write(buf,0,bytesRead);
        }
        output.writeShort(-1);
        fileIn.close();
    }



    public void receiveFile(File file) throws IOException {
        FileOutputStream fileOut = new FileOutputStream(file);
        byte[] buf = new byte[Short.MAX_VALUE];
        int bytesSent;        
        while( (bytesSent = input.readShort()) != -1 ) {
            input.readFully(buf,0,bytesSent);
            fileOut.write(buf,0,bytesSent);
        }
        fileOut.close();
    }    
} // end class

放弃“助手”类。它对您没有帮助。

关于java - 使用java套接字从客户端向服务器发送文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13331406/

相关文章:

c - 在 C 中以 block 的形式将内存写入套接字

Java 套接字到 C 套接字

python - Python TCP 套接字 recv(1) 与 recv(n) 的效率

java - Spring boot 2.2.0 - 分段文件上传失败并出现错误

java - 努力设置 pom.xml 文件。不断收到 Maven 强制执行器规则 2 错误

Java 从命令行调用列表文件

java - 无法编辑/更新 xml 文件

java - JMeter 无法使用 JDBC 连接连接到 Phoenix

Java 和解析 XML

Python/Pandas - 使用制表符作为分隔符读取 csv 文件无法按预期工作