当前位置: 首页 > news >正文

沈阳双兴建设集团有限公司网站网站建设策划方案范文

沈阳双兴建设集团有限公司网站,网站建设策划方案范文,wordpress动态导航侧边栏,seo网站优化系统最近在整理Java IO相关内容#xff0c;会遇到一些以前没有注意的问题#xff0c;特此记录#xff0c;以供自查和交流。 需求#xff1a; 基于Java的BIO API#xff0c;实现简单的客户端和服务端通信模型#xff0c;客户端使用BufferedReader的readLine方法读取System.i…最近在整理Java IO相关内容会遇到一些以前没有注意的问题特此记录以供自查和交流。 需求 基于Java的BIO API实现简单的客户端和服务端通信模型客户端使用BufferedReader的readLine方法读取System.in上的用户输入然后通过字节输出流发送给服务端服务端使用BufferedReader的readLine方法读取客户端的数据进行打印 问题 服务端没有打印出客户端发送的数据且卡在BufferedReader的readLine方法处 上代码 客户端 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket;/*** 基于BIO的TCP网络通信的客户端接收控制台输入的数据然后通过字节流发送给服务端**/ class ChatClient {public static void main(String[] args) throws IOException {// 连接serverSocket serverSocket new Socket(localhost, 9999);System.out.println(client connected to server);// 读取用户在控制台上的输入并发送给服务器InputStream in System.in;// sendDataToServerByByteStream(in, serverSocket.getOutputStream()); //服务端可以正常接收sendDataToServerByCharStream(in, serverSocket.getOutputStream()); //服务端无法正常接收}/*** 通过字节流发送数据给服务端*/private static void sendDataToServerByByteStream(InputStream in, OutputStream outputStream) throws IOException {byte[] buffer new byte[1024];int len;// read操作阻塞直到有数据可读while ((len in.read(buffer)) ! -1) {System.out.println(client receive data from console in : new String(buffer, 0, len));// 发送数据给服务器端outputStream.write(new String(buffer, 0, len).getBytes()); // 此时buffer中是有换行符的}}/*** 通过字符流使用readLine发送数据给服务端*/private static void sendDataToServerByCharStream(InputStream in, OutputStream outputStream) {String content null;try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(in));) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里content bufferedReader.readLine();while (content ! exit) {System.out.println(client send data: content);outputStream.write(content.getBytes()); // 字节流没有添加换行符content bufferedReader.readLine();}} catch (IOException e) {throw new RuntimeException(e);}} }服务端代码 import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket;/*** 基于BIO的TCP网络通信的服务端可以接收多个客户端连接通过字节流接收客户端发送的消息* 一个客户端需要使用一个线程* todo线程资源复用** author freddy*/ class ChatServer {public static void main(String[] args) throws IOException {// 开启server 监听端口ServerSocket serverSocket new ServerSocket(9999);while (true) {Socket client serverSocket.accept(); // 阻塞操作需要新的线程处理客户端// 接收Client数据并转发new Thread(new ServerThread(client)).start();}} }/*** 服务端的线程一个客户端对应一个*/ class ServerThread implements Runnable {Socket socket;public ServerThread(Socket socket) {this.socket socket;}Overridepublic void run() {System.out.println(server had a client socket);// 获取输入流程读取用户输入// 持续接收Client数据并打印readDataFromClientByCharStream(); // 无法正常读取客户端发送过来的数据}/*** 使用字符流读取客户端的数据主要使用readLine*/private void readDataFromClientByCharStream() {try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(socket.getInputStream()));) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里String content bufferedReader.readLine();while (content ! exit) {System.out.println(serer receive data from socket : content);content bufferedReader.readLine();}} catch (IOException e) {System.out.println(Client disconnect );}} }先运行服务端在启动客户端然后在客户端的控制台发送数据 可以看到客户端和服务端之间已经建立了连接但是服务端并没有打印日志说明服务端的程序卡在了代码1这个地方。 为什么呢 那我们需要去看java.io.BufferedReader#readLine()这个方法的源码 基于debug方式我们可以看到java.io.BufferedReader#readLine()这个方法 先调用java.io.BufferedReader#fill方法读取输入流的内容 可以看到这里读取到的内容是hello 5个字符没有换行符 fill方法调用完后回到readLine方法的charLoop中 可以看到for循环中有个条件当读取到的字节中包含\n 或者 \r的时候会设置eol true后面会根据该eol标志return读取到的字符串结束readLine方法 当读取到的字节中没有\n 或者 \r的时候eol falsereadLine方法就会回到 bufferLoop循环中的fill方法继续读取输入流程中的内容 如果输入流中有内容会读取后继续判断是否有换行符\n 或者 \r 如果输入流中没有内容那么fill方法会阻塞在java.io.Reader#read(char[], int, int)方法 这就是服务端的代码阻塞在java.io.BufferedReader#readLine()的原因 解决问题 找到问题后那么我们就好解决问题了 解决思路如下 1.服务端仍然使用java.io.BufferedReader#readLine()读取客户端的数据的话那么客户端发送数据时就必须代换行符 1.1  客户端在发送完用户数据后继续Socket.getOutputStream().write(\r\n.getBytes());发送换行符 1.2 调用增强的输出流的api直接发送数据的同时发送换行符 比如PrintWriter pw new PrintWriter(outputStream, true); pw.println(content); // 添加换行符 1.3 调整客户端获取用户输入数据的方式把用户的换行符直接读取过来后用原来的方式发送 private static void sendDataToServerByByteStream(InputStream in, OutputStream outputStream) throws IOException {byte[] buffer new byte[1024];int len;// read操作阻塞直到有数据可读while ((len in.read(buffer)) ! -1) {System.out.println(client receive data from console in : new String(buffer, 0, len));// 发送数据给服务器端outputStream.write(new String(buffer, 0, len).getBytes()); // 此时buffer中是有换行符的}} 2.服务端调整数据读取方式 客户端使用java.io.DataOutputStream#writeUTF(java.lang.String)发送给数据 服务端使用java.io.DataInputStream#readUTF()方法接收数据 这种方式是相当于客户端在发送数据的时候给数据规定了格式服务端可以根据约定的格式来正确读取数据类似于java.io.DataOutputStream#writeShort方法 关于这种思想用的地方很多 常用来解决RPC发送数据的粘包问题 在常用的RPC框架如Netty中就有使用在大数据框架如MapReduce中也有writeShort类似方式序列号和反序列话 完整的客户端和服务端验证代码如下 客户端 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket;/*** 基于BIO的TCP网络通信的客户端接收控制台输入的数据然后通过字节流发送给服务端**/ class ChatClient {public static void main(String[] args) throws IOException {// 连接serverSocket serverSocket new Socket(localhost, 9999);System.out.println(client connected to server);// 读取用户在控制台上的输入并发送给服务器InputStream in System.in;// sendDataToServerByByteStream(in, serverSocket.getOutputStream()); //服务端可以正常接收sendDataToServerByCharStream(in, serverSocket.getOutputStream()); // 服务端无法正常接收}/*** 通过字节流发送数据给服务端*/private static void sendDataToServerByByteStream(InputStream in, OutputStream outputStream) throws IOException {byte[] buffer new byte[1024];int len;// read操作阻塞直到有数据可读while ((len in.read(buffer)) ! -1) {System.out.println(client receive data from console in : new String(buffer, 0, len));// 发送数据给服务器端outputStream.write(new String(buffer, 0, len).getBytes()); // 此时buffer中是有换行符的}}/*** 通过字符流使用readLine发送数据给服务端*/private static void sendDataToServerByCharStream(InputStream in, OutputStream outputStream) {String content null;try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(in));) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里content bufferedReader.readLine();while (content ! exit) {System.out.println(client send data: content);outputStream.write(content.getBytes()); // 字节流没有添加换行符content bufferedReader.readLine();}} catch (IOException e) {throw new RuntimeException(e);}}/*** 通过字符流使用readLine发送数据给服务端*/private static void sendDataToServerByCharStream2(InputStream in, OutputStream outputStream) {String content null;try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(in));) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里content bufferedReader.readLine();while (content ! exit) {System.out.println(client send data: content);outputStream.write(content.getBytes()); // 字节流没有添加换行符outputStream.write(\r\n.getBytes());content bufferedReader.readLine();}} catch (IOException e) {throw new RuntimeException(e);}}/*** 通过字符流使用readLine发送数据给服务端*/private static void sendDataToServerByCharStream3(InputStream in, OutputStream outputStream) {String content null;try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(in));PrintWriter pw new PrintWriter(outputStream, true);) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里content bufferedReader.readLine();while (content ! exit) {System.out.println(client send data: content);pw.println(content); // 添加换行符content bufferedReader.readLine();}} catch (IOException e) {throw new RuntimeException(e);}}private static void sendDataToServerByCharStream4(InputStream in, OutputStream outputStream) {String content null;try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(in));DataOutputStream pw new DataOutputStream(outputStream);) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里content bufferedReader.readLine();while (content ! exit) {System.out.println(client send data: content);pw.writeUTF(content);pw.flush();content bufferedReader.readLine();}} catch (IOException e) {throw new RuntimeException(e);}} }服务端 import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket;/*** 基于BIO的TCP网络通信的服务端可以接收多个客户端连接通过字节流接收客户端发送的消息* 一个客户端需要使用一个线程* todo线程资源复用** author freddy*/ class ChatServer {public static void main(String[] args) throws IOException {// 开启server 监听端口ServerSocket serverSocket new ServerSocket(9999);while (true) {Socket client serverSocket.accept(); // 阻塞操作需要新的线程处理客户端// 接收Client数据并转发new Thread(new ServerThread(client)).start();}} }/*** 服务端的线程一个客户端对应一个*/ class ServerThread implements Runnable {Socket socket;public ServerThread(Socket socket) {this.socket socket;}Overridepublic void run() {System.out.println(server had a client socket);// 获取输入流程读取用户输入// 持续接收Client数据并打印readDataFromClientByCharStream(); // 无法正常读取客户端发送过来的数据}/*** 使用字节流读取客户端的数据*/private void readDataFromClientByByteStream() {try (InputStream inputStream socket.getInputStream()) {byte[] buffer new byte[1024];int len;// read操作阻塞直到有数据可读while ((len inputStream.read(buffer)) ! -1) {System.out.println(serer receive data from socket : new String(buffer, 0, len));}} catch (IOException e) {System.out.println(socket disconnect );}}/*** 使用字符流读取客户端的数据主要使用readLine*/private void readDataFromClientByCharStream() {try (BufferedReader bufferedReader new BufferedReader(new InputStreamReader(socket.getInputStream()));) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里String content bufferedReader.readLine();while (content ! exit) {System.out.println(serer receive data from socket : content);content bufferedReader.readLine();}} catch (IOException e) {System.out.println(Client disconnect );}}/*** 使用字符流读取客户端的数据主要使用readLine*/private void readDataFromClientByCharStream2() {try (DataInputStream dataInputStream new DataInputStream(socket.getInputStream());) {// 此时content中已经没有换行符了,// 并且如果原始字节流中没有换行符该方法内部会循环等待换行符相当于阻塞在这里String content dataInputStream.readUTF();while (content ! exit) {System.out.println(serer receive data from socket : content);content dataInputStream.readUTF();}} catch (IOException e) {System.out.println(Client disconnect );}} }参考java网络编程 BufferedReader的readLine方法读不到数据的原因_java后台服务端bufferedreader不能读全数据 前台出现超时提示-CSDN博客
http://www.zqtcl.cn/news/643504/

相关文章:

  • 如何在百度上搜索到自己的网站提升关键词
  • asp net做网站建设英文网站的公司
  • 旅游英文网站 建设需求WordPress首页id
  • 南宁网站如何制作网站seo查询站长之家
  • 网站备案太麻烦门户网站模板
  • 九江建网站多少钱打开云南省住房和城乡建设厅网站
  • 合肥市门户网站wordpress登陆不上
  • 摄影网站在线建设办公室设计装修
  • 深圳市移动端网站建设游戏网站建设与策划方案
  • wap版网站 加app提示厦门网站seo优化
  • 旅游网站 功能建设银行网站会员
  • 公园网站建设wordpress 分类目录使用英文
  • 苏州高端网站设计制作wordpress改固定连接
  • 门户网站开源sae安装wordpress
  • 建设彩票网站需要哪些要求城乡与住房建设厅网站首页
  • 公司做网站费用计入什么科目网络建设规划
  • 外贸网站建设案例深圳设计网站培训
  • 龙岗地区做网站公司北京装饰公司排行 2019
  • 大企业网站建设方案wordpress博客模板查询
  • 手机网站建设动态公司做网站效果怎么样
  • 网站推广和优化教程上海网络科技有限公司招聘
  • 即墨建网站价格商城二次开发
  • 网站排名易下拉教程怎么做网店运营
  • 聊城做网站公司聊城博达海外服务器租用多少钱一年
  • 手机上网站做国外销售都上什么网站
  • 网站建设与管理报告书做电销有什么资料网站
  • 网站建设哪家最好企业商城网站建设方案
  • 舟山市建设工程质量监督站网站网页版微信二维码加载失败
  • 金融网站html5模板给自己家的公司做网站好做吗
  • 新农村建设投诉在哪个网站上海做电缆桥架的公司网站