Java实现本地Socket通信(三)
今天任务较少也较为简单本节任务账号登录半成品可视化界面一、账号登陆我们知道账号输入操作是需要在客户端进行的所以这里我们需要在客户端封装登陆方法login在这里读取输入并传递给服务端账号信息public void login(OutputStream os){ Scanner scnew Scanner(System.in); System.out.println(请输入账号); String accountsc.nextLine(); byte[] acaccount.getBytes(); try { os.write(ac.length);//不可以发送字符串的长度必须发送字节的长度 os.write(ac); os.flush(); } catch (IOException e) { throw new RuntimeException(e); } }接着我们需要在服务端读取传递过来的信息用封装函数proLogein实现并返回读取到的用户名public String proLogein(Socket socket){ try { InputStream issocket.getInputStream(); int lenis.read(); byte[] msgsnew byte[len]; is.read(msgs); String userNamenew String(msgs); System.out.println(用户userName登录了); return userName; } catch (IOException e) { throw new RuntimeException(e); } }tips.这里proLogein方法应该在消息处理方法proClintMsg处创建线程时调用如下public void proClintMsg(Socket socket){ //注意循环速度太快导致cpu被占满io流根本没机会运行所以这里加一个println让cpu空闲下来 new Thread(()-{ //登录 //读取用户名 String UserNameproLogein(socket); ClientUser cunew ClientUser(UserName,socket); //保存ClientUser对象 SocketList.add(cu); while(true) { try { InputStream iscu.socket.getInputStream(); System.out.println(监听cu.socket.getPort()消息中);//顺序不对 String msgreceive(is); replyMsg(cu,msg); } catch (IOException e) { throw new RuntimeException(e); } } }).start(); }用户信息类Client内部定义了账号account用户名和套接字socket这里就不展示代码了至此用户登录的功能雏形便完成了二、实现界面可视化这里我们需要创建一个UI类ClientUI首先先创建窗口对象并调用内部函数设置相关参数尺寸、关闭方法、显示格式、布局等JFrame jfnew JFrame(聊天室); jf.setSize(500,600); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭 jf.setLocationRelativeTo(null);//居中显示 //默认边框布局随后添加相关组件最后记得设置可见文本显示JTextAreaJTextArea msgAreanew JTextArea();//支持多行显示所以不用jtext显示文字 JScrollPane scrollPanenew JScrollPane(msgArea);//滚动显示面板 jf.add(scrollPane, BorderLayout.NORTH);输入框JTestFieldJTextField msgFieldnew JTextField();//输入框 msgField.setPreferredSize(new Dimension(400,0)); msgField.setBackground(Color.LIGHT_GRAY); jf.add(msgField, BorderLayout.WEST);发送键JButtonJButton sendButtonnew JButton(发送); sendButton.setPreferredSize(new Dimension(100,0)); jf.add(sendButton, BorderLayout.EAST);tips.这里不要忘记为按钮添加监听方法下面是新版本的简便写法sendButton.addActionListener(e - sendMsg(msgArea,msgField)); //e相当于是内部类创建一个临时内部类可以直接调用本类中的函数不需要单独写一个监听类到这里界面基本就创建完成了接下来需要做的便是功能迁移三、功能迁移我们的代码大体上是不需要做什么改动的现在我们需要做的是读取可视化界面内输入框里的内容并让其显示在文本框上消息发送方法如下public void sendMsg(JTextArea msgArea,JTextField msgField){ String msgmsgField.getText(); //send(msg); System.out.println(发送中...); //设置到自己的界面上 msgArea.append(我msg\n); //发送消息 client.send(msg); }显示如下在showui中添加新线程new Thread(()-{ while(true) { String msgclient.readMsg(); // System.out.print(接收消息); // System.out.println(msg); // System.out.println(请输入); msgArea.append(msg\n); } }).start();四、完整代码·Clientimport java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner; public class Client { //由于外部需要访问socket所以定义为全局变量 Socket socketnull; public void init(){ try { socketnew Socket(127.0.0.1,54321); login(socket.getOutputStream()); } catch (Exception e) { throw new RuntimeException(e); } } public void send(String message){ try { OutputStream ossocket.getOutputStream(); byte[] msgsmessage.getBytes(); int lenmsgs.length; os.write(len); os.write(msgs); os.flush(); } catch (Exception e) { throw new RuntimeException(e); } } public String readMsg(){ try { InputStream issocket.getInputStream(); int lenis.read(); byte[] msgsnew byte[len]; is.read(msgs); return new String(msgs); } catch (Exception e) { throw new RuntimeException(e); } } public void login(OutputStream os){ Scanner scnew Scanner(System.in); System.out.println(请输入账号); String accountsc.nextLine(); byte[] acaccount.getBytes(); try { os.write(ac.length);//不可以发送字符串的长度必须发送字节的长度 os.write(ac); os.flush(); } catch (IOException e) { throw new RuntimeException(e); } } }·ClientUIimport javax.swing.*; import java.awt.*; import java.util.Scanner; public class ClientUI extends JFrame { Client clientnew Client(); public void showUI(){ //先加载客户端 并进行登录 client.init(); JFrame jfnew JFrame(聊天室); jf.setSize(500,600); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭 jf.setLocationRelativeTo(null);//居中显示 //默认边框布局 JTextArea msgAreanew JTextArea();//支持多行显示所以不用jtext显示文字 // JTextPane msgPanenew JTextPane(msgArea); JScrollPane scrollPanenew JScrollPane(msgArea);//滚动显示 scrollPane.setPreferredSize(new Dimension(0,500)); JTextField msgFieldnew JTextField();//输入框 msgField.setPreferredSize(new Dimension(400,0)); msgField.setBackground(Color.LIGHT_GRAY); JButton sendButtonnew JButton(发送); sendButton.setPreferredSize(new Dimension(100,0)); //JLabel labelnew JLabel(当前状态); jf.add(scrollPane, BorderLayout.NORTH); jf.add(msgField, BorderLayout.WEST); jf.add(sendButton, BorderLayout.EAST); jf.setVisible(true); sendButton.addActionListener(e - sendMsg(msgArea,msgField));//e相当于是内部类创建一个临时内部类可以直接调用本类中的函数不需要单独写一个监听类 new Thread(()-{ while(true) { String msgclient.readMsg(); // System.out.print(接收消息); // System.out.println(msg); // System.out.println(请输入); msgArea.append(msg\n); } }).start(); } public void sendMsg(JTextArea msgArea,JTextField msgField){ String msgmsgField.getText(); //send(msg); System.out.println(发送中...); //设置到自己的界面上 msgArea.append(我msg\n); //发送消息 client.send(msg); } public static void main(String[] args) { ClientUI clientUInew ClientUI(); clientUI.showUI(); } }·ClientUserimport java.net.Socket; public class ClientUser { String account; Socket socket; public ClientUser(String account,Socket socket){ this.accountaccount; this.socketsocket; } public ClientUser(){ } }·Serverimport java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class Server { ServerSocket ssnull; ArrayListClientUser SocketListnew ArrayList(); public void init(){ try { ssnew ServerSocket(54321); } catch (IOException e) { throw new RuntimeException(e); } } public Socket listen(){ try { return ss.accept(); } catch (IOException e) { throw new RuntimeException(e); } } public void send(String message, OutputStream os){ try { //mission:通过os把这个消息发送出去 byte[] msgsmessage.getBytes(); int lenmsgs.length; os.write(len);//发送长度 os.write(msgs); os.flush(); } catch (IOException e) { throw new RuntimeException(e); } } public String receive(InputStream is){ try { int lenis.read(); byte[] msgsnew byte[len]; is.read(msgs); // for(int i0;ilen;i){ // msgs[i] (byte) is.read(); // } String msgnew String(msgs); System.out.println(收到msg); return msg; } catch (IOException e) { throw new RuntimeException(e); } } public void replyMsg(ClientUser client,String msg){ //转发消息 for(int i0;iSocketList.size();i){ ClientUser cuSocketList.get(i); Socket scu.socket; if (s!client.socket){ try { String m client.account说msg;//注意拼接逻辑 send(m,s.getOutputStream()); } catch (IOException e) { throw new RuntimeException(e); } } } } public void proClintMsg(Socket socket){ //注意循环速度太快导致cpu被占满io流根本没机会运行所以这里加一个println让cpu空闲下来 new Thread(()-{ //登录 //读取用户名 String UserNameproLogein(socket); ClientUser cunew ClientUser(UserName,socket); //保存ClientUser对象 SocketList.add(cu); while(true) { try { InputStream iscu.socket.getInputStream(); System.out.println(监听cu.socket.getPort()消息中);//顺序不对 String msgreceive(is); replyMsg(cu,msg); } catch (IOException e) { throw new RuntimeException(e); } } }).start(); } public String proLogein(Socket socket){ try { InputStream issocket.getInputStream(); int lenis.read(); byte[] msgsnew byte[len]; is.read(msgs); String userNamenew String(msgs); System.out.println(用户userName登录了); return userName; } catch (IOException e) { throw new RuntimeException(e); } } public static void main(String[] args) { Server servernew Server(); //初始化 server.init(); //匿名内部类放到线程中(监听连接部分) new Thread(()-{ while(true) { System.out.println(等待连接...); Socket s server.listen(); System.out.println(有新的连接s.getInetAddress()s.getPort()); server.proClintMsg(s);//处理客户端消息 每个客户端一个线程 } }).start(); } }

相关新闻

蓝桥杯算法竞赛:DFS与BFS搜索算法核心原理与真题实战

蓝桥杯算法竞赛:DFS与BFS搜索算法核心原理与真题实战

1. 搜索专题在蓝桥杯中的核心地位与备考价值如果你正在准备蓝桥杯,尤其是软件类(C/C、Java、Python组)的比赛,那么“搜索”这个专题,绝对是你绕不开、也绝不能轻视的核心高地。我参加过几届蓝桥杯的评审和辅导工作&…

2026/7/29 9:07:11阅读更多 →
C#字符串长度全解析:码元、字符与字节长度的区别与应用

C#字符串长度全解析:码元、字符与字节长度的区别与应用

1. 从一次“字符截断”事故说起 那天下午,我正在调试一个处理多语言用户名的数据导出功能。逻辑很简单:从数据库读取用户信息,生成CSV文件。测试时一切正常,直到一个日本用户的名字“山田 太郎”出现在列表里。导出的文件在其他系…

2026/7/29 9:07:11阅读更多 →
涂胶显影机(Track)各职级技术岗人才综合评估结论及录用判定标准

涂胶显影机(Track)各职级技术岗人才综合评估结论及录用判定标准

一、总则(终审核心逻辑) 本标准为Track技术招聘最终终审唯一依据,完全贯通公司整套Track招聘体系:各职级14维面试打分卡、两轮分层技术面试、HR分层分级面试、面试官权责体系、职级薪酬体系、法务竞业合规审核与竞业储备体系。 本制度固化三方评审权重,明确技术、HR、法…

2026/7/29 9:07:11阅读更多 →
UniApp原生插件开发与离线打包调试实战指南

UniApp原生插件开发与离线打包调试实战指南

1. 项目概述:为什么需要掌握UniApp原生插件与离线打包? 如果你正在用UniApp开发跨平台应用,并且已经走到了需要调用手机硬件(比如蓝牙、NFC、特定传感器)或者集成第三方SDK(比如人脸识别、地图导航&#x…

2026/7/29 10:25:29阅读更多 →
ROS编程实战:从零构建虚拟温度传感器与监控系统

ROS编程实战:从零构建虚拟温度传感器与监控系统

1. 项目缘起:为什么从“鱼香ROS”开始聊ROS编程?如果你最近在B站、知乎或者一些机器人技术社区里逛,大概率会刷到“鱼香ROS”或者“小鱼ROS一键安装”这些词。这其实反映了一个非常真实的现状:很多对机器人操作系统(RO…

2026/7/29 10:25:29阅读更多 →
从OTA测试报告解读2.4GHz天线性能:TRP、EIRP与辐射方向图实战分析

从OTA测试报告解读2.4GHz天线性能:TRP、EIRP与辐射方向图实战分析

1. 项目概述:从一份测试报告看透天线性能在无线产品研发的圈子里,天线性能的评估一直是个既基础又关键的环节。无论你是做Wi-Fi路由器、蓝牙耳机,还是其他任何工作在2.4GHz ISM频段的物联网设备,天线设计的好坏直接决定了产品的“…

2026/7/29 10:25:29阅读更多 →
TI TIDA-00339 IO-Link PHY评估板硬件设计与应用实践

TI TIDA-00339 IO-Link PHY评估板硬件设计与应用实践

1. 项目概述与核心价值如果你正在工业自动化领域折腾传感器或执行器的通信接口,大概率绕不开IO-Link这个协议。它不是什么高深莫测的黑科技,本质上就是一种标准化的、点对点的串行通信协议,目标就是把现场那些五花八门的模拟量传感器、数字量…

2026/7/29 10:25:29阅读更多 →
2026年DevOps平台盘点,一站式平台推荐

2026年DevOps平台盘点,一站式平台推荐

随着2025年中国DevOps工具市场规模突破85亿元、年复合增长率达24.3%,2026年的选型已不再是单纯比功能。企业面临的核心矛盾从“怎么跑流水线”转向“如何在信创合规、成本控制和团队协作之间找到平衡”。工具链碎片化(Jira搭配GitLab再拼Jenkins&#xf…

2026/7/29 10:25:29阅读更多 →
MIPI CSI-2协议引擎:核心架构、时序配置与调试实战

MIPI CSI-2协议引擎:核心架构、时序配置与调试实战

1. 协议引擎核心架构与数据流转MIPI CSI-2协议引擎,在图像处理链路中扮演着“交通枢纽”和“数据包装工”的双重角色。它位于图像数据源(如DSS的CBUFF)和物理层(D-PHY)之间,核心任务是将上游送来的原始像素…

2026/7/29 10:23:29阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“! 在构建复杂的 Agent 系统时,我们经常会遇到这样的场景:Agent 正在执行一个多步骤的任务,比如“下单购买商品”,但执行到一半时,我们…

2026/7/29 0:01:46阅读更多 →
自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…

2026/7/29 0:01:46阅读更多 →
【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:01:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/29 4:31:51阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →