首页 > 代码库 > Java 网络编程 字符流的发送与接收 自定义数据边界

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();
    }
}

这样,服务器就能获取客户端输入的所有内容了。