Socket编程(ServerScoket, Socket) 回声例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiaotuwoaini/article/details/72844448

你的bug越离奇,你的错误越低级!

服务端:

package dusk.echo.simple;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by dushangkui on 2017/6/2.
 */
public class Server {

    public static void main(String[] args) throws IOException {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress(9000));
        while(true){
            Socket socket = serverSocket.accept();
            executor.submit(new Processor(socket));
        }
    }
}

处理器:

package dusk.echo.simple;

import java.io.*;
import java.net.Socket;

/**
 * Created by dushangkui on 2017/6/2.
 */
public  class Processor implements Runnable{
    private Socket socket =null;

    public Processor(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br=null;
        PrintWriter writer=null;
        System.out.println("get a connection");
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
            while(true){
                String msg=br.readLine();
                if("bye".equals(msg)) break;
                System.out.println("server recived: " + msg);
                writer.println(msg);
                writer.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
            if(writer!=null) {
                try {
                    writer.close();
                } catch (Exception e) {
                }
            }
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
    }
}

客户端:

package dusk.echo.simple;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by dushangkui on 2017/6/2.
 */
public class Client {
    public static void main(String[] args){
        BufferedReader br=null;
        PrintWriter  writer=null;
        Socket socket = new Socket();
        try {
            socket.connect(new InetSocketAddress("localhost", 9000));
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new PrintWriter (new OutputStreamWriter(socket.getOutputStream()));
            Scanner scanner = new Scanner(System.in);
            while(true){
                String msg =scanner.next();
                writer.println(msg);
                writer.flush();
                if (msg.equals("bye")) {
                    break;
                }
                System.out.println("Recieved Server msg: " + br.readLine());
            }
        }catch(Exception e){
            e.printStackTrace();
            if(br!=null) {
                try {
                    br.close();
                } catch (IOException e1) {
                }
            }
            if(writer!=null) {
                try {
                    writer.close();
                } catch (Exception e1) {
                }
            }
            try {
                socket.close();
            } catch (IOException e1) {
            }
        }
    }
}

但是如果我客户端使用BufferedWriter去写数据的时候发现服务器端读取不到,仔细想了想,原来是我用BufferedWriter写的时候没有在消息的结尾插入换行符,导致服务器端明明有数据到达确读不完整一行,因此阻塞。

看写法:

        BufferedReader br=null;
        BufferedWriter  writer=null;
        Socket socket = new Socket();
        try {
            socket.connect(new InetSocketAddress("localhost", 9000));
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new BufferedWriter (new PrintWriter(socket.getOutputStream()));
            Scanner scanner = new Scanner(System.in);
            while(true){
                String msg =scanner.next();
                writer.write(msg+"\n");
                writer.flush();
                if (msg.equals("bye")) {
                    break;
                }
                System.out.println("Recieved Server msg: " + br.readLine());
            }
        }catch(Exception e){

看来BufferedReader和BufferedWriter是很方便但是不注意也会惹麻烦,正如行内的话:你的bug越离奇,你的错误越低级。

我们看BufferedReader的readLine源码

    String readLine(boolean ignoreLF) throws IOException {
        StringBuffer s = null;
        int startChar;

        synchronized (lock) {
            ensureOpen();
            boolean omitLF = ignoreLF || skipLF;

        bufferLoop:
            for (;;) {

                if (nextChar >= nChars)
                    fill();
                if (nextChar >= nChars) { /* EOF */
                    if (s != null && s.length() > 0)
                        return s.toString();
                    else
                        return null;
                }
                boolean eol = false;
                char c = 0;
                int i;

                /* Skip a leftover '\n', if necessary */
                if (omitLF && (cb[nextChar] == '\n'))
                    nextChar++;
                skipLF = false;
                omitLF = false;

            charLoop:
                for (i = nextChar; i < nChars; i++) {
                    c = cb[i];
                    if ((c == '\n') || (c == '\r')) {
                        eol = true;
                        break charLoop;
                    }
                }

                startChar = nextChar;
                nextChar = i;

                if (eol) {
                    String str;
                    if (s == null) {
                        str = new String(cb, startChar, i - startChar);
                    } else {
                        s.append(cb, startChar, i - startChar);
                        str = s.toString();
                    }
                    nextChar++;
                    if (c == '\r') {
                        skipLF = true;
                    }
                    return str;
                }

                if (s == null)
                    s = new StringBuffer(defaultExpectedLineLength);
                s.append(cb, startChar, i - startChar);
            }
        }
    }

可以看到我们到流的结尾或者遇见\r或\n才会返回一行

猜你喜欢

转载自blog.csdn.net/jiaotuwoaini/article/details/72844448