写入比从套接字读取更快
Writing faster than reading from a socket
我做了一个实验,我创建了一个有 2 个线程的程序:一个服务器线程和一个客户端线程。
服务器线程接受来自客户端的连接,执行一个长过程(由 sleep()
模拟),并打印结果。
另一方面,客户端发送消息的速度非常快。
见代码:
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketTest {
public static void main(String[] args) throws InterruptedException {
Thread serverThread = new Thread(() -> server());
Thread clientThread = new Thread(() -> client());
serverThread.start();
clientThread.start();
serverThread.join();
clientThread.join();
}
private static void server() {
try (
ServerSocket listener = new ServerSocket( 1234 );
Socket client = listener.accept()){ // wait for connection
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
//process
Thread.sleep(1000);
System.out.println(someString);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void client () {
try (Socket server = new Socket(InetAddress.getLocalHost(), 1234))
{
while (true) {
OutputStream out = server.getOutputStream();
// write a newline or carriage return delimited string
PrintWriter pout = new PrintWriter(out, true);
pout.println("Hello!");
// send the the string
pout.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我 运行 程序时,我得到以下输出:
Hello!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
...
现在我不确定我是否理解了 100%...
但是我做了运行输入大小为2的幂(包括/n
)的实验,输出没有被截断。
谁能给我解释一下:
- 内部情况如何?
- 为什么没有报错?
- 你会怎样克服这个问题?
谢谢!!
private static void server() {
...
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
这会为 while 循环的每个 运行 创建一个新的 BufferedReader
。但是 readline
不仅会从套接字中读取一行。相反,它将读取大量数据,检查其中是否有行尾,如果还没有行尾则读取更多数据等等,最后 return 该行。其余的读取数据保存在BufferedReader
中。通过在循环 运行 结束时隐式放弃 BufferedReader
并在新循环 运行 开始时创建一个新循环 运行 ,您放弃了缓冲区中已经从套接字读取的所有数据.
相反,您应该在循环外创建 BufferedReader
并在那里使用它,这样就不会放弃任何数据:
private static void server() {
...
InputStream in = client.getInputStream();
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
while (true) {
// read a newline or carriage-return-delimited string
String someString = bin.readLine();
我做了一个实验,我创建了一个有 2 个线程的程序:一个服务器线程和一个客户端线程。
服务器线程接受来自客户端的连接,执行一个长过程(由 sleep()
模拟),并打印结果。
另一方面,客户端发送消息的速度非常快。
见代码:
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketTest {
public static void main(String[] args) throws InterruptedException {
Thread serverThread = new Thread(() -> server());
Thread clientThread = new Thread(() -> client());
serverThread.start();
clientThread.start();
serverThread.join();
clientThread.join();
}
private static void server() {
try (
ServerSocket listener = new ServerSocket( 1234 );
Socket client = listener.accept()){ // wait for connection
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
//process
Thread.sleep(1000);
System.out.println(someString);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void client () {
try (Socket server = new Socket(InetAddress.getLocalHost(), 1234))
{
while (true) {
OutputStream out = server.getOutputStream();
// write a newline or carriage return delimited string
PrintWriter pout = new PrintWriter(out, true);
pout.println("Hello!");
// send the the string
pout.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我 运行 程序时,我得到以下输出:
Hello!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
...
现在我不确定我是否理解了 100%...
但是我做了运行输入大小为2的幂(包括/n
)的实验,输出没有被截断。
谁能给我解释一下:
- 内部情况如何?
- 为什么没有报错?
- 你会怎样克服这个问题?
谢谢!!
private static void server() {
...
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
这会为 while 循环的每个 运行 创建一个新的 BufferedReader
。但是 readline
不仅会从套接字中读取一行。相反,它将读取大量数据,检查其中是否有行尾,如果还没有行尾则读取更多数据等等,最后 return 该行。其余的读取数据保存在BufferedReader
中。通过在循环 运行 结束时隐式放弃 BufferedReader
并在新循环 运行 开始时创建一个新循环 运行 ,您放弃了缓冲区中已经从套接字读取的所有数据.
相反,您应该在循环外创建 BufferedReader
并在那里使用它,这样就不会放弃任何数据:
private static void server() {
...
InputStream in = client.getInputStream();
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
while (true) {
// read a newline or carriage-return-delimited string
String someString = bin.readLine();