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

来源:互联网 发布:js 点击保存图片 编辑:程序博客网 时间:2024/04/30 18:39

你的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才会返回一行

原创粉丝点击