我读过一些关于StackOverflow的问题,我们通常使用条件(c = inputStream.read()) == -1)
来检测是否到达“流的结尾”。然而,我也读到过,如果套接字关闭,套接字的OutputStream只发送“流结束”消息。
这使得这个服务器代码。。
public class Server {
public static int port = 27018;
public static void main(String[] args) throws IOException, InterruptedException {
char c = ' ';
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server started");
Socket connectionSocket = serverSocket.accept();
serverSocket.close();
String bufferOuputString = "";
InputStream in = connectionSocket.getInputStream();
OutputStream out = connectionSocket.getOutputStream();
System.out.println("Connection established on port " + port);
out.write("Welcome to my server !".getBytes());
System.out.println("Waiting for client messages");
while(c != '/'){
c = (char) in.read();
if(c == '*'){
System.out.println(bufferOuputString);
bufferOuputString = "";
} else {
bufferOuputString += c;
}
}
connectionSocket.close();
}
}
。。。和这个客户代码一起。。
public class Client {
public static int port = 27018;
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("127.0.0.1", port)) {
int c;
Scanner sc = new Scanner(System.in);
String bufferInputString = "";
String bufferString = "";
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
while((c = in.read()) != -1){
bufferInputString += (char) c;
}
System.out.println(bufferInputString);
while(!bufferString.contains("/")){
System.out.println("You can write messages to server:");
bufferString = sc.nextLine() + "*";
out.write(bufferString.getBytes());
}
}
}
}
没用因为客户端等待流结束信号(in.read() = -1
),而这个信号永远不会到来,所以它一直被InputStream.read()
调用阻塞。
为了记录在案,我尝试将其作为服务器代码来进一步检查套接字的“规则”:
public class Server {
public static int port = 27018;
public static void main(String[] args) throws IOException, InterruptedException {
char c = ' ';
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server started");
Socket connectionSocket = serverSocket.accept();
serverSocket.close();
String bufferOuputString = "";
InputStream in = connectionSocket.getInputStream();
OutputStream out = connectionSocket.getOutputStream();
System.out.println("Connection established on port " + port);
out.write("Welcome to my server !".getBytes());
Thread.sleep(3000);
connectionSocket.close();
}
}
3秒钟后,客户端打印出...
...然后进入无限循环,因为我忘记更改第二个while
循环。因此,这确认了套接字的OutputStream
对象只在Socket.close()
处发送“流结束”。我的问题是:为什么选择这种设计?
1条答案
按热度按时间uz75evzq1#
不是默认的。
在 Socket 类中似乎没有任何东西会传输 -1 值。
这里是 Socket#close 的源代码,这里是 ServerSocket#close。
当 -1 到达数据流的末尾时,由 read 方法发送。
因此,它将取决于接口-例如,* FTP * 使用 \r\n 序列来表示传输的结束。
这个概念是为了增加组件之间的一致性,因为数据传输是“昂贵的”。
此外,它类似于 HTTP 头包含 content-length 的方式-这减少了,一些人称之为 * polling *-本质上,while((c = in.read())!= -1),没有块。
正确。Socket 正在访问 SocketInputStream#read 方法,如果没有数据,该方法将阻塞。