[英]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有點令人擔憂。 至少與預期不符。
順便說一下,我的正常模式是在main
: new Server().exec();
等等。 這將刪除所有這些靜態變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.