gpt4 book ai didi

java - BufferedWriter/PrintWriter/OutputStreamWriter 在调用 .close() 之前不刷新缓冲区(通过套接字输出流)

转载 作者:行者123 更新时间:2023-11-29 03:19:52 28 4
gpt4 key购买 nike

每当我对标题中的任何编写器(正在包装 OutputStreamWriter)调用 .flush() 时,刷新的数据都不会发送;然而,当 .close() 在编写器上调用时,它会刷新并且服务器可以读取数据。我不知道我是否错误地调用了 .write().readLine() ,或者如果因为读取操作已经被阻止,那就是问题所在?我需要找到一种在不关闭套接字的情况下刷新数据的方法(我将在另一个程序中使用它)。在我拥有的两个 SSCCE 中,都有用于调试的 System.out.println()。在客户端中,它会转到“检查 4”并且什么都不循环(它在实际程序中做了更多的读取和写入,只是不能在示例中关闭它)。在服务器中,它开始“检查 2”并在 reader.readLine() 处阻塞。我已经阅读了有关 SO 的文章,但我想到的是 readLine() 对于网络程序来说不是一个好主意,我应该实现自己的协议(protocol);然而,这些帖子都没有指向一个好的教程站点,或者任何其他具有好的网络编码教程的站点。以下是 SSCCE:

客户SSCCE

package testClient;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class Client {

public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1",48878);
System.out.println("check 1");
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));
System.out.println("check 2");
pw.write("Hello StackOverFlow.");
System.out.println("check 3");
pw.flush();
System.out.println("check 4");
while(true){}
} catch (IOException e) {
e.printStackTrace();
}
}

}

服务器SSCCE

package testServer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {


public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(48878);
Socket client = ss.accept();
System.out.println("check 1");
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
System.out.println("check 2");
byte[] buffer = new byte[20];
int i = 0;;
int x;
while((x=reader.read())!=-1) {
buffer[i] += (byte)x;
i = i++;
}
String text = new String(buffer,"UTF-8");
System.out.println("check 3");
System.out.println(text);
client.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

最佳答案

尝试使用 PrintWriter自动刷新属性一旦调用新的行方法就刷新数据。在流中写入任何数据后无需调用 flush。

Unlike the PrintStream class, if automatic flushing is enabled it will be done only when one of the println, printf, or format methods is invoked, rather than whenever a newline character happens to be output.

示例代码:

客户:

PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"),true);
pw.println("Hello StackOverFlow.");

服务器:

BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
System.out.println(reader.readLine());

关于java - BufferedWriter/PrintWriter/OutputStreamWriter 在调用 .close() 之前不刷新缓冲区(通过套接字输出流),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24312147/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com