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才会返回一行
阅读全文
0 0
- Socket编程(ServerScoket, Socket) 回声例子
- ServerScoket与Socket的关系
- raw socket编程例子
- socket编程代码例子
- raw socket编程例子
- raw socket编程例子
- boost socket编程 例子
- raw socket编程例子 .
- boost socket编程 例子
- SOCKET 编程例子
- Socket通信编程例子
- socket编程例子
- socket编程基于UDP的服务端客户端回声程序
- linux socket编程 daemon例子
- Windows Socket API编程例子
- socket编程:select 用法 例子
- java socket编程小例子
- Linux socket 编程简单例子
- 计算机跟学习板通信
- 危险系数
- ZigBee_CC2530_08H_HAL层分析
- ES6(八) 对象的扩展
- 使用spring task或spring quartz执行任务执行两次
- Socket编程(ServerScoket, Socket) 回声例子
- Android
- Java I/O关于缓冲区部分提高性能的源码分析【Stream】
- mac 安装python虚拟环境,多版本共存
- (转载)Linux内核源代码情景分析---第四章 进程与进程调度
- 三角形法恢复空间点深度
- 优秀的主页设计
- 关于mysql中设置隔一段事件调用一个存储过程的事件
- Java正则表达式入门