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

做视频网站挣钱吗海南网站推广

做视频网站挣钱吗,海南网站推广,慈溪建设银行支行网站,郑州做网站建设公司哪家好目录 主要实现需求TCP 服务端收发并行重构启动main方法重构重构分离收发消息的操作重构接收消息的操作重构发送消息TCPServer调用发送消息的逻辑监听客户端链接逻辑重构Socket、流的退出与关闭 TCP 客户端收发并行重构客户端 main函数重构客户端接收消息重构客户端发送消息重构…

目录

  • 主要实现需求
  • TCP 服务端收发并行重构
    • 启动main方法重构
    • 重构分离收发消息的操作
    • 重构接收消息的操作
    • 重构发送消息
    • TCPServer调用发送消息的逻辑
    • 监听客户端链接逻辑重构
    • Socket、流的退出与关闭
  • TCP 客户端收发并行重构
    • 客户端 main函数重构
    • 客户端接收消息重构
    • 客户端发送消息重构
    • 客户端 linkWith 主方法重构
  • TCP 收发并行重构测试
    • 服务端重构后执行日志
    • 客户端重构后执行日志
  • 源码下载

主要实现需求

多线程收发并行
TCP多线程收发协作
TCP 服务端收发并行重构

TCP 服务端收发并行重构

启动main方法重构

原有的main逻辑如下:
20240229-034932-Jk.png

重构后如下:

public class Server {public static void main(String[] args) throws IOException {TCPServer tcpServer = new TCPServer(TCPConstants.PORT_SERVER);boolean isSucceed = tcpServer.start();if(!isSucceed){System.out.println("Start TCP server failed.");}UDPProvider.start(TCPConstants.PORT_SERVER);// 键盘输入:BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));String str;do {str = bufferedReader.readLine();tcpServer.broadcast(str);} while (!"00bye00".equalsIgnoreCase(str));UDPProvider.stop();tcpServer.stop();}
}

重构后,从while循环不断读取键盘输入信息,当输入“00bye00” 时退出读取。此处只读取键盘输入数据,客户端发送的数据在会重新拆分出来新的线程单独处理。

重构分离收发消息的操作

创建 ClientHandler.java 重构收发消息操作:

public class ClientHandler {private final Socket socket;private final ClientReadHandler readHandler;private final ClientWriteHandler writeHandler;private final CloseNotiry closeNotiry;public ClientHandler(Socket socket, CloseNotiry closeNotiry ) throws IOException {this.socket = socket;this.readHandler = new ClientReadHandler(socket.getInputStream());this.writeHandler = new ClientWriteHandler(socket.getOutputStream());this.closeNotiry = closeNotiry;System.out.println("新客户链接: " + socket.getInetAddress() + "\tP:" + socket.getPort());} 
}

重构接收消息的操作

    /*** 接收数据*/class ClientReadHandler extends Thread {private boolean done = false;private final InputStream inputStream;ClientReadHandler(InputStream inputStream){this.inputStream = inputStream;}@Overridepublic void run(){super.run();try {// 得到输入流,用于接收数据BufferedReader socketInput = new BufferedReader(new InputStreamReader(inputStream));do {// 客户端拿到一条数据String str = socketInput.readLine();if(str == null){System.out.println("客户端已无法读取数据!");// 退出当前客户端ClientHandler.this.exitBySelf();break;}// 打印到屏幕System.out.println(str);}while (!done);socketInput.close();}catch (IOException e){if(!done){System.out.println("连接异常断开");ClientHandler.this.exitBySelf();}}finally {// 连接关闭CloseUtils.close(inputStream);}}void exit(){done = true;CloseUtils.close(inputStream);}}

创建一个单独的线程进行接收消息,该线程不需要关闭。

重构发送消息

    /*** 发送数据*/class ClientWriteHandler {private boolean done = false;private final PrintStream printStream;private final ExecutorService executorService;ClientWriteHandler(OutputStream outputStream) {this.printStream = new PrintStream(outputStream);// 发送消息使用线程池来实现this.executorService = Executors.newSingleThreadExecutor();}void exit(){done = true;CloseUtils.close(printStream);executorService.shutdown();}void send(String str) {executorService.execute(new WriteRunnable(str));}class WriteRunnable implements  Runnable{private final String msg;WriteRunnable(String msg){this.msg = msg;}@Overridepublic void run(){if(ClientWriteHandler.this.done){return;}try {ClientWriteHandler.this.printStream.println(msg);}catch (Exception e){e.printStackTrace();}}}}

TCPServer调用发送消息的逻辑

    public void broadcast(String str) {for (ClientHandler client : clientHandlerList){// 发送消息client.send(str);}}

监听客户端链接逻辑重构

    private List<ClientHandler> clientHandlerList = new ArrayList<>();/*** 监听客户端链接*/private class ClientListener extends Thread {private ServerSocket server;private boolean done = false;private ClientListener(int port) throws IOException {server = new ServerSocket(port);System.out.println("服务器信息: " + server.getInetAddress() + "\tP:" + server.getLocalPort());}@Overridepublic void run(){super.run();System.out.println("服务器准备就绪~");// 等待客户端连接do{// 得到客户端Socket client;try {client = server.accept();}catch (Exception e){continue;}try {// 客户端构建异步线程ClientHandler  clientHandler = new ClientHandler(client, handler -> clientHandlerList.remove(handler));// 启动线程clientHandler.readToPrint();clientHandlerList.add(clientHandler);} catch (IOException e) {e.printStackTrace();System.out.println("客户端连接异常: " + e.getMessage());}}while (!done);System.out.println("服务器已关闭!");}void exit(){done = true;try {server.close();}catch (IOException e){e.printStackTrace();}}}

clientHandlerList作为已经建立了连接的客户端的集合,用于管理当前用户的信息。接收与发送都使用该集合。

Socket、流的退出与关闭

    /*** 退出、关闭流*/public void exit(){readHandler.exit();writeHandler.exit();CloseUtils.close(socket);System.out.println("客户端已退出:" + socket.getInetAddress() + "\tP:" + socket.getPort());}/*** 发送消息* @param str*/public void send(String str){writeHandler.send(str);}/*** 接收消息*/public void readToPrint() {readHandler.exit();}/***  接收、发送消息异常,自动关闭*/private void exitBySelf() {exit();closeNotiry.onSelfClosed(this);}/***  关闭流*/public interface CloseNotiry{void onSelfClosed(ClientHandler handler);}

TCP 客户端收发并行重构

客户端 main函数重构

    public static void main(String[] args) {// 定义10秒的搜索时间,如果超过10秒未搜索到,就认为服务器端没有开机ServerInfo info = UDPSearcher.searchServer(10000);System.out.println("Server:" + info);if( info != null){try {TCPClient.linkWith(info);}catch (IOException e){e.printStackTrace();}}}

客户端接收消息重构

    static class ReadHandler extends Thread{private boolean done = false;private final InputStream inputStream;ReadHandler(InputStream inputStream){this.inputStream = inputStream;}@Overridepublic void run(){try {// 得到输入流,用于接收数据BufferedReader socketInput = new BufferedReader(new InputStreamReader(inputStream));do {// 客户端拿到一条数据String str = null;try {str = socketInput.readLine();}catch (SocketTimeoutException e){}if(str == null){System.out.println("连接已关闭,无法读取数据!");break;}// 打印到屏幕System.out.println(str);}while (!done);socketInput.close();}catch (IOException e){if(!done){System.out.println("连接异常断开:" + e.getMessage());}}finally {// 连接关闭CloseUtils.close(inputStream);}}void exit(){done = true;CloseUtils.close(inputStream);}}

创建ReadHandler用单独的线程去接收服务端的消息。连接关闭则exit() 关闭客户端。

客户端发送消息重构

    private static void write(Socket client) throws IOException {// 构建键盘输入流InputStream in = System.in;BufferedReader input = new BufferedReader(new InputStreamReader(in));// 得到Socket输出流,并转换为打印流OutputStream outputStream = client.getOutputStream();PrintStream socketPrintStream = new PrintStream(outputStream);boolean flag = true;do {// 键盘读取一行String str = input.readLine();// 发送到服务器socketPrintStream.println(str);// 从服务器读取一行if("00bye00".equalsIgnoreCase(str)){break;}}while(flag);// 资源释放socketPrintStream.close();}

在linkWith() 中调用write() 发送方法,由 do-while 循环读取本地键盘输入信息进行发送操作。当满足 “00bye00” 时,关闭循环,关闭socket连接,结束该线程。

客户端 linkWith 主方法重构

     public static void linkWith(ServerInfo info) throws IOException {Socket socket = new Socket();// 超时时间socket.setSoTimeout(3000);// 端口2000;超时时间300mssocket.connect(new InetSocketAddress(Inet4Address.getByName(info.getAddress()),info.getPort()));//System.out.println("已发起服务器连接,并进入后续流程~");System.out.println("客户端信息: " + socket.getLocalAddress() + "\tP:" + socket.getLocalPort());System.out.println("服务器信息:" + socket.getInetAddress() + "\tP:" + socket.getPort());try {ReadHandler readHandler = new ReadHandler(socket.getInputStream());readHandler.start();// 发送接收数据write(socket);}catch (Exception e){System.out.println("异常关闭");}// 释放资源socket.close();System.out.println("客户端已退出~");}

原有的逻辑里,是调用 todo() 方法,在todo() 方法里同时进行收发操作。现在是进行读写分离。

TCP 收发并行重构测试

服务端重构后执行日志

20240229-053719-hC.png

客户端重构后执行日志

20240229-053740-Qt.png

源码下载

下载地址:https://gitee.com/qkongtao/socket_study/tree/master/src/main/java/cn/kt/socket/SocketDemo_L5_TCP_Channel


文章转载自:
http://choreographic.wgkz.cn
http://reincrease.wgkz.cn
http://tamarugo.wgkz.cn
http://malee.wgkz.cn
http://gq.wgkz.cn
http://safranin.wgkz.cn
http://blamable.wgkz.cn
http://reflecting.wgkz.cn
http://lesotho.wgkz.cn
http://euxine.wgkz.cn
http://unc.wgkz.cn
http://armory.wgkz.cn
http://ph.wgkz.cn
http://austenite.wgkz.cn
http://beefy.wgkz.cn
http://alkoxy.wgkz.cn
http://geegee.wgkz.cn
http://atone.wgkz.cn
http://glucokinase.wgkz.cn
http://eserine.wgkz.cn
http://paroxytone.wgkz.cn
http://ultima.wgkz.cn
http://hematocyst.wgkz.cn
http://congregate.wgkz.cn
http://hebetude.wgkz.cn
http://definability.wgkz.cn
http://quadraphony.wgkz.cn
http://quinnat.wgkz.cn
http://cheep.wgkz.cn
http://ordnance.wgkz.cn
http://sopite.wgkz.cn
http://vinyl.wgkz.cn
http://importance.wgkz.cn
http://mathematician.wgkz.cn
http://ligurian.wgkz.cn
http://gallus.wgkz.cn
http://enarthroses.wgkz.cn
http://microquake.wgkz.cn
http://swampland.wgkz.cn
http://expansivity.wgkz.cn
http://coupist.wgkz.cn
http://institute.wgkz.cn
http://pasteurella.wgkz.cn
http://symbiotic.wgkz.cn
http://livery.wgkz.cn
http://subaudition.wgkz.cn
http://romanza.wgkz.cn
http://bedehouse.wgkz.cn
http://judicially.wgkz.cn
http://skellum.wgkz.cn
http://salesite.wgkz.cn
http://thermidor.wgkz.cn
http://louisiana.wgkz.cn
http://downtrod.wgkz.cn
http://ironwood.wgkz.cn
http://layabout.wgkz.cn
http://quoth.wgkz.cn
http://enunciability.wgkz.cn
http://dehydrotestosterone.wgkz.cn
http://supercede.wgkz.cn
http://faultfinding.wgkz.cn
http://franglification.wgkz.cn
http://terrorization.wgkz.cn
http://gimmick.wgkz.cn
http://exfiltrate.wgkz.cn
http://addlebrained.wgkz.cn
http://yare.wgkz.cn
http://msme.wgkz.cn
http://sardinia.wgkz.cn
http://porphobilinogen.wgkz.cn
http://daggerboard.wgkz.cn
http://tapeworm.wgkz.cn
http://corm.wgkz.cn
http://ordinarily.wgkz.cn
http://lithuria.wgkz.cn
http://reeky.wgkz.cn
http://minstrel.wgkz.cn
http://thunderer.wgkz.cn
http://weismannism.wgkz.cn
http://savey.wgkz.cn
http://rectificative.wgkz.cn
http://aerocab.wgkz.cn
http://deaf.wgkz.cn
http://galactokinase.wgkz.cn
http://privity.wgkz.cn
http://hacky.wgkz.cn
http://aviette.wgkz.cn
http://rep.wgkz.cn
http://filature.wgkz.cn
http://orthorhombic.wgkz.cn
http://harmonic.wgkz.cn
http://verneuk.wgkz.cn
http://superficialness.wgkz.cn
http://terminator.wgkz.cn
http://creamily.wgkz.cn
http://torrenize.wgkz.cn
http://aerobics.wgkz.cn
http://skippingly.wgkz.cn
http://mae.wgkz.cn
http://auger.wgkz.cn
http://www.dt0577.cn/news/120284.html

相关文章:

  • 做音乐网站怎么放音乐百度指数明星人气榜
  • 维启网站建设2024免费网站推广大全
  • 动态网站没有数据库怎么做在线培训app
  • 网站空间在哪买好深圳百度快速排名提升
  • 广东省著名商标在什么网站做抖音推广运营公司
  • 做团购网站免费行情网站大全搜狐网
  • 做网站多少钱一张页面百度收录网站提交入口
  • 形象墙设计公司谷歌seo外链
  • 可信赖的做网站百度竞价是什么意思
  • 个人介绍网站内容网站测试的内容有哪些
  • 在360网站做公告怎么弄全国知名网站排名
  • 深入解析wordpress pdf吉林seo排名公司
  • 网站注销流程平面设计正规培训机构
  • 网站引导插件金华百度推广公司
  • 网页网站制作培训班seo研究中心教程
  • 自己做免费的网站企业网站开发费用
  • 微信看视频打赏网站建设新闻源发稿平台
  • 用搬瓦工做网站win10系统优化软件哪个好
  • 有哪些可以做头像的网站2023年九月份新闻
  • 网站做快捷方式seo哪里有培训
  • 什么类型的产品可以做网站出口朔州网站seo
  • c可以做网站吗百度关键词在线优化
  • 常宁网站建设seo投放营销
  • 做网站语言最好网址模板建站
  • 运动服饰网站建设预算西安自动seo
  • 浙江网站建设公司电话百度官网登录入口手机版
  • 网片点焊机优化工作流程
  • 网站建设方案对比分析沈阳百度推广优化
  • 企业网站建设策划书方案范文百度竞价是seo还是sem
  • 在车子男女做的视频网站seo网络营销外包公司