3

Javaでソケット作業を行っており、送信するデータをエンコードしようとしています。その部分は正しく機能していますが、何らかの理由で、エンコードされた文字列全体がソケット経由で送信されません。3分割でお送りするようです。

クライアントは MyBufferedReader クラス (下にあります) から単純な readLine() を実行し、サーバーはそれを次のように送信します。

    private void sendFile(File f, String dest){ //The file to be sent and the destination
        System.out.println("Sending file started..");

        try {
            this.out.println("CMD MKFILE " + dest + "/" + f.getName());
            //TODO send the file
        }catch(Exception e){
            e.printStackTrace();
        }
    }

クライアントはこれを受け取ります: CMD MKFILE C:\Users\Lolmewn\Documents\test/dir/n/linebreaそして別の読み取りの後k!.txt

MyBufferedReader および MyPrintWriter クラスは次のようになります。

MyBufferedReader:

    @Override
    public String readLine() throws IOException {
        String read = super.readLine();
        System.out.println("UNDEC: " + read);
        try {
            System.out.println("DEC: " + decode(read));
            return decode(read);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return read;
    }

    public static String decode(String b) throws Exception {
        ByteArrayInputStream bais = new ByteArrayInputStream(b.getBytes("UTF-8"));
        InputStream b64is = MimeUtility.decode(bais, "base64");
        byte[] tmp = new byte[b.length()];
        int n = b64is.read(tmp);
        byte[] res = new byte[n];
        System.arraycopy(tmp, 0, res, 0, n);
        return new String(res);
     }

および MyPrintWriter:

    private String hash(String x) {
        try {
            return encode(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return x;
    }

    public static String encode(String b) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        OutputStream b64os = MimeUtility.encode(baos, "base64");
        b64os.write(b.getBytes("UTF-8"));
        b64os.close();
        return new String(baos.toByteArray());
     }

何が起こっていますか?どうすれば修正できますか?

注意してください: 私はこれらのソケットで非同期作業を行っています。つまり、while(read != null) ステートメントだけを使用することはできません。それは、そこにあるはずのない他のデータもそこにある原因になります。

4

1 に答える 1

1

まずこれはさておき: 複数のスレッド/クライアントから送信している場合は、それぞれに対して 1 つのソケットを開く必要があります (accept() のように)。そうすれば、異なるクライアントからのメッセージが互いにインターリーブできなくなります。

今、私はソケットごとに単一のクライアントのみを想定しています(合理的です):

while(read != null) だけでは使えない

1 つのメッセージを次のメッセージと区別できる単純なプロトコルを実装する必要があります。そうすれば、サーバーは 1 つのメッセージを次のメッセージと区別できます。

于 2012-02-13T12:49:47.050 に答える