簡體   English   中英

DataOutputStream僅在System.out.println之前工作

[英]DataOutputStream works only preceded by System.out.println

輸入/輸出流出現另一個問題。 在這里,我將數據從服務器發送到客戶端。 在發送數據之前,服務器會發送一個小字符串,只是要告訴客戶端他將發送的內容,因此客戶端知道他應該使用哪個函數來接收。

我很好地接收了第一個字符串,但是隨后我沒有得到好的整數,在此之后,我收到的第二個字符串為“ null”。

而且,如果我在將DataOutputStream與dos.writeInt結合使用之前先做一個System.out.println,那么一切都很好。 我不明白。 這是代碼:

服務器:

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;


public class Server {

    private static OutputStream out;

    static byte[] generateRandomBytes(int len) {
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[len];
        random.nextBytes(bytes);
        return bytes;
    }

    public static void sendType(String type) {
        PrintWriter textWriter = new PrintWriter(out);
        textWriter.println(type);
        textWriter.flush();
    }

    public static void sendKeyNumber(int keyNumber) {
        sendType("keyNumber");
        try {
            DataOutputStream dos = new DataOutputStream(out);
            //System.out.println("Sending key number: " + keyNumber);
            dos.writeInt(keyNumber);
            //dos.flush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

    public static void sendKey(byte[] key) {
        sendType("key");
        try {
            DataOutputStream dos = new DataOutputStream(out);
            //System.out.println("key length to send: " +key.length);
            dos.writeInt(key.length); // write length of the byte array
            //dos.flush();
            dos.write(key);
            //dos.flush();
            System.out.println("key send: " +key);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Socket clientSocket ;        
        System.out.println("ouverture du server");
        try {
            ServerSocket serverSocket = new ServerSocket(2004);
            clientSocket = serverSocket.accept(); 
            out = clientSocket.getOutputStream();

            sendKeyNumber(0);
            byte[] keyBytes = generateRandomBytes(32);
            sendKey(keyBytes);

            clientSocket.close();


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

客戶:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.crypto.spec.SecretKeySpec;



public class Main {

    static InputStream in;

    public static int receiveKeyNumber() {
        DataInputStream dis = new DataInputStream(in);
        int keyNumber = 0;
        try {
            keyNumber = dis.readInt();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return keyNumber;
    }

    public static SecretKeySpec receiveKey() {
        DataInputStream dIn = new DataInputStream(in);
        int length;
        byte[] keyBytes = null;
        try {
            length = dIn.readInt();                   // read length of incoming message
            System.out.println("key length: " + length);
            if(length!=32) {
                System.err.println("Incorrect size for key: "+ length);
            }       
            else {
                keyBytes = new byte[length];
                dIn.readFully(keyBytes, 0, keyBytes.length); 
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        SecretKeySpec aesKey = new SecretKeySpec(keyBytes, "AES");
        return aesKey;
    }


    public static void main(String[] args) {

        Socket clientSocket;
        try {
            clientSocket = new Socket(InetAddress.getLocalHost(),2004);

            in = clientSocket.getInputStream();
            while(!clientSocket.isClosed()) {
                BufferedReader textReader = new BufferedReader(new InputStreamReader(in));
                String type = textReader.readLine();
                System.out.println(type);

                if(type.equals("keyNumber")) {
                    int KN = receiveKeyNumber();
                    System.out.println(KN);
                }

                if(type.equals("key")) {
                    SecretKeySpec key = receiveKey();
                    System.out.println(key);
                }
            }

            clientSocket.close();

        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }
}

結束以下是我不執行System.out.println時得​​到的(在客戶端控制台中):

keyNumber
1801812234

null

我總是得到相同的怪異數字。 我嘗試將其轉換為ASCII,但不可讀。

有什么建議嗎?

在這種情況下,發送二進制數據時,請完全使用DataOutputStream。 (或者,您可以輸入文字。)

private static DataOutputStream out;

out = new DataOutputStream(clientSocket.getOutputStream());

public static void sendType(String type) {
    out.writeUTF(type);
    out.flush();
}

沖洗對於二進制對話很重要。

包裝類DataOutputStream,Printer,BufferedReader等的問題是它們會啟動自己的“游標”,並會在關閉時自行關閉包裝的I / O。 擁有幾個DataOutputStreams有點令人擔憂。 至少與預期不符。

順便說一下,我的正常模式是在mainnew Server().exec(); 等等。 這將刪除所有這些靜態變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM