1

これは課題です。

ここでどこが間違っているのかについて、少しアドバイスを探しています。私の目的は、ファイルからテキストを読み取り、それをサーバーに送信して、そのテキストを新しいファイルに書き込むことです。

問題はそれを行う方法が正確にわからないため、多くの例を見てきましたが、どれもあまり役に立ちませんでした。

プログラムをそのまま説明します。ユーザーは、そのコードの 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)
4

1 に答える 1

3

MyStreamSocketクラスで Socket を拡張する必要はありません。不思議なエラー メッセージは、MyStreamSocket によって表される Socket が何にも接続されていないために発生します。そのsocketメンバーによって参照される Socket は、接続されているものです。したがって、MyStreamSocket から入力ストリームを取得すると、実際には接続されません。これは、クライアントがシャットダウンすることを意味するエラーを引き起こします。これにより、ソケットが閉じられ、サーバーが正式に報告します

BufferedReader を使用すると問題が発生します。常に可能な限り多くをバッファーに読み込むため、ファイル転送の開始時に「200」メッセージを読み取り、次に送信されるファイルの最初の数キロバイトを読み取り、文字データとして解析します。その結果、大量のバグが発生します。

今すぐ BufferedReader を取り除き、代わりに DataInputStream と DataOutputStream を使用することをお勧めします。writeUTF および readUTF メソッドを使用して、テキスト コマンドを送信できます。ファイルを送信するには、単純なチャンク エンコーディングをお勧めします。

コードを提供すると、おそらく最も簡単です。

まず、クライアント クラス。

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

「ヘルパー」クラスを捨てます。それはあなたを助けていません。

于 2012-11-11T19:52:40.097 に答える