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:10 阅读更多 →
C#字符串长度全解析:码元、字符与字节长度的区别与应用

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

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

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

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

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

2026/7/29 9:07:10 阅读更多 →

最新新闻

AI客服质检从0到1落地指南:3步搭建高准确率质检模型(附开源代码库)

AI客服质检从0到1落地指南:3步搭建高准确率质检模型(附开源代码库)

更多请点击: https://kaifayun.com 第一章:AI客服质检从0到1落地指南:3步搭建高准确率质检模型(附开源代码库) 构建高准确率的AI客服质检模型并非黑盒工程,而是可复现、可迭代的数据驱动过程。本章聚焦从原…

2026/7/29 9:12:12 阅读更多 →
市场旅行社品牌

市场旅行社品牌

在当前的旅行社市场中,有多个品牌因其各自的特点和服务优势而受到消费者的青睐。以下是一些知名的旅行社品牌及其特色:康辉旅游集团山东国际旅行社有限公司(简称“山东康辉”):作为中国康辉旅游集团在山东设立的企业&a…

2026/7/29 9:12:12 阅读更多 →
Unity WebGL构建中emscriptenArgs参数失效的深度解析与解决方案

Unity WebGL构建中emscriptenArgs参数失效的深度解析与解决方案

1. 问题现象与背景:一个让开发者头疼的“幽灵”参数 如果你正在或曾经为Unity WebGL平台打包,并且尝试过通过 PlayerSettings.WebGL.emscriptenArgs 来传递自定义的Emscripten编译参数,那么你很可能遇到过这个令人困惑的场景:你…

2026/7/29 9:12:12 阅读更多 →
数据链路层核心原理与实战:从帧封装到交换机、VLAN与ARP解析

数据链路层核心原理与实战:从帧封装到交换机、VLAN与ARP解析

1. 项目概述:为什么数据链路层是网络世界的“交警”与“质检员”搞了这么多年网络,从校园里的思科实验箱到机房里的核心交换机,再到云上虚拟网络的配置,我越来越觉得,数据链路层是整个网络体系里最“接地气”、也最容易…

2026/7/29 9:12:12 阅读更多 →
小米8抓包TikTok失败?Frida脚本绕过SSL Pinning与代理检测实战

小米8抓包TikTok失败?Frida脚本绕过SSL Pinning与代理检测实战

1. 项目概述:当TikTok遇上小米8,抓包为何频频“失联”?如果你是一名移动安全研究员、逆向工程师,或者只是一个对TikTok内部数据流感到好奇的开发者,那么“抓包”这个操作对你来说一定不陌生。无论是用Wireshark、Fiddl…

2026/7/29 9:12:12 阅读更多 →
ESP32三合一电子工作台:波形发生器、蓝牙电压表与网页示波器

ESP32三合一电子工作台:波形发生器、蓝牙电压表与网页示波器

1. 项目概述:一个零件的“瑞士军刀”如果你手头恰好有一块ESP32开发板,并且对电子测量和信号生成有点兴趣,但又不想被一堆分立的运放、电阻电容和复杂的电路板搞得头大,那么这个项目可能就是为你量身定做的。它的核心思路极其简单…

2026/7/29 9:11:11 阅读更多 →

日新闻

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

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

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

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻