Java 网络编程 字符流的发送与接收 自定义数据边界
在网络编程中,客户端调用了flush方法,就会将缓存在字符流中的文本发送给服务器,服务器该怎样判断客户端发送的文本已经结束了呢?
我们先看一个例子:
客户端:
import java.io.IOException; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Scanner; /** * Created by 290248126 on 14-5-9. */ public class Client { public static void main(String[] args) throws IOException, InterruptedException { Socket socket = new Socket(); socket.connect(new InetSocketAddress("localhost", 8088), 1000); socket.setSoTimeout(5000); PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); //键盘输入流 Scanner keyboardScanner = new Scanner(System.in); while (keyboardScanner.hasNextLine()) { String line = keyboardScanner.nextLine(); System.out.println("你输入:" + line); if ("ok".equals(line)) {//当客户端输入ok,代表客户要发送的信息已经完毕 break; } //这里只是写到printWriter的缓存去,兵们有真实的发送到服务器端 printWriter.println(line); } System.out.println("客户端发送..."); printWriter.flush(); System.out.println("刷新,发送到服务器。"); Thread.sleep(200000); socket.close(); } }
服务器:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * Created by 290248126 on 14-5-9. */ public class Server { public static void main(String[] args) throws IOException, InterruptedException { ServerSocket serverSocket = new ServerSocket(8088); Socket socket = serverSocket.accept(); Scanner scanner = new Scanner(socket.getInputStream()); StringBuilder stringBuilder = new StringBuilder(); //循环里面没有判断客户发送结束的边界,因此while循环一直在阻塞运行着 //除非客户断开连接,或者客户端断开输出流,此时才返回false,才会跳出循环。 //要想获得用户发送的所有文本信息,就要自定义一个边界来判断。 while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println("检测到客户端输入:"+line); stringBuilder.append(line); } System.out.println("循环外"); System.out.println(stringBuilder.toString()); Thread.sleep(200000); } }
上面的服务器端,不会输出“循环外”,因为scanner.hasNextLine()返回false的条件是,客户端断开连接或者客户端断开输出流。
我们下面定义一个数据边界来解决这个问题。
服务器:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * Created by 290248126 on 14-5-9. */ public class Server2 { public static void main(String[] args) throws IOException, InterruptedException { ServerSocket serverSocket = new ServerSocket(8088); Socket socket = serverSocket.accept(); Scanner scanner = new Scanner(socket.getInputStream()); StringBuilder stringBuilder = new StringBuilder(); //重点判断边界 while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println("检测到客户端输入:"+line); if("bianjie".equals(line)) {//判断是否是边界 System.out.println("检测到边界,客户端输入完毕"); break; } stringBuilder.append(line+"\n"); } System.out.println("循环外"); System.out.println("客户端发过来:"); System.out.println(stringBuilder.toString()); System.out.println("——————————"); Thread.sleep(200000); } }
客户端:
import java.io.IOException; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Scanner; /** * Created by 290248126 on 14-5-9. */ public class Client2 { public static void main(String[] args) throws IOException, InterruptedException { Socket socket = new Socket(); socket.connect(new InetSocketAddress("localhost", 8088), 1000); socket.setSoTimeout(5000); PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); //键盘输入流 Scanner keyboardScanner = new Scanner(System.in); while (keyboardScanner.hasNextLine()) { String line = keyboardScanner.nextLine(); System.out.println("你输入:" + line); if ("ok".equals(line)) {//当客户端输入ok,代表客户要发送的信息已经完毕 printWriter.println("bianjie");//使用它作为数据边界,告知服务器我这边已经发送完毕 break; } //这里只是写到printWriter的缓存去,兵们有真实的发送到服务器端 printWriter.println(line); } System.out.println("客户端发送..."); printWriter.flush(); System.out.println("刷新,发送到服务器。"); Thread.sleep(200000); socket.close(); } }
这样,服务器就能获取客户端输入的所有内容了。
本文出自 无忧之路 - 博客园