一、先公示代码
1.1、服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while (true) {
// 一直等待socket连接
System.out.println("等待建立连接");
Socket accept = serverSocket.accept();
System.out.println("建立连接成功");
InputStream is = accept.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = "";
while ((str = br.readLine()) != null) {
System.out.println("获取到服务端数据:"+str);
}
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String reply = scanner.nextLine();
OutputStream os = accept.getOutputStream();
os.write(reply.getBytes());
os.flush();
if (reply.equals("退出")){
break;
}
os.close();
br.close();
is.close();
accept.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2 客户端
package nj.zb.kb21.socket.test;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
while (true) {
try {
Socket socket = new Socket("127.0.0.1", 5000);
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
OutputStream os = socket.getOutputStream();
String str = scanner.next();
os.write(str.getBytes());
os.flush();
os.close();
// socket.shutdownOutput();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String reply = "";
while ((reply = br.readLine()) != null) {
System.out.println(reply);
}
if (str.equals("退出")){
break;
}
br.close();
is.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、说明问题
2.1、理想状态
在以上代码中想想的效果应该是下方图片效果,双方逐个发送信息,来完成对话知道一方输入退出
2.2、现实情况
出现了以下情况(到达os.close()把所有资源释放。),通过询问,查资料得知是由于流的原因导致。
2.3、另一种情况
将os.close() 放到最后,出现了下方情况, 使得服务端并没有获取到客户端的数据
三、说明情况
这里说明其中socket和流里面的三个方法
方法 | 描述 |
---|---|
OutputStream中的flush() | 刷新输出流并强制写入所有缓冲的输出字节 |
OutputStream中的close() | 关闭此输出流并释放与此流相关的任何系统资源 |
Socket中的shutdownOutput() | 禁用此套接字的输出流 |
上方客户端的方法应当使用socket中的shutdownOutput()方法
使用flush()方法 并没有关闭socket中的输出流导致程序以为还会写入字节
使用clost()方法 彻底关闭了输出流 并且还把socket也给释放了,导致客户端关停