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

时间:2018-08-16 13:36:19

标签: java system.out dataoutputstream

输入/输出流遇到另一个问题。在这里,我将数据从服务器发送到客户端。在发送数据之前,服务器会发送一个小字符串,只是要告诉客户端他将发送的内容,因此客户端知道他应该使用哪个函数来接收。

我很好地接收了第一个字符串,但是随后我没有得到好的整数,之后我收到的第二个字符串为“ 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,但是不可读。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

在这种情况下,发送二进制数据时,请完全使用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();中进行操作。 那将删除所有这些静态变量。