- 浏览: 218819 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
zzhyq:
有没有后台是ASHX 的呀
Ext.tree.TreePanel -
693593336:
谢谢作者分享,正好用上
Ext.tree.TreePanel -
greatwqs:
提供一个下载的demo不是更好
基于servlet的 Freemarker Demo
写得不是很规范,但也写挺多的注释了。一般是可以看得懂的啦。没什么特别的功能,仅仅是群聊!ps:玩玩而已。直接贴代码。。。比较适合刚学Socket编程的看。界面的代码是用Netbean直接生成的,显得很笨重!
Code:
- //====================Server.java=================================
- packagecc.nothing2012.blogServlet;
- importjava.io.DataInputStream;
- importjava.io.DataOutputStream;
- importjava.io.IOException;
- importjava.net.InetAddress;
- importjava.net.ServerSocket;
- importjava.net.Socket;
- importjava.util.Vector;
- publicclassServer{
- privateServerSocketserverSocket;
- privateSocketsocket;
- privatestaticVector<ServerObject>vector=newVector<ServerObject>();
- privateServerObjectserverObject;
- privatestaticVector<String>vecIPs=newVector<String>();//记录所有的IP对象
- publicServer(){
- try{
- serverSocket=newServerSocket(55555);
- System.out.println("服务器已经启动!");//后台提示
- while(true){
- try{
- socket=serverSocket.accept();//一直在等待连接
- p(socket);
- finalInetAddressaddress=socket.getInetAddress();
- p("那个丫的连接的IP:"+address);
- p(vector.size());//打印连接前,登陆客户端的个数。
- serverObject=newServerObject(socket);//说明一个客户端连接上了,新建对象线程。
- vector.addElement(serverObject);//往向量里面添加一个客户端。
- p("add"+address.getHostAddress());
- vecIPs.addElement("add"+address.getHostAddress());
- serverObject.start();//启动一个线程
- p("客户端个数:"+vector.size());//打印连接后,登陆客户端的个数。
- p("IP个数:"+vecIPs.size());
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }catch(IOExceptione){
- p("服务器启动失败!");
- }
- }
- publicvoidp(Objecto){
- System.out.println(o);
- }
- publicstaticvoidmain(String[]args){
- newServer();
- }
- classServerObjectextendsThread{
- privateDataOutputStreamout=null;
- privateDataInputStreamin=null;
- privateSocketsocket=null;
- //每个连接过来的客户端,将初始化这样的一个对象。
- publicServerObject(Socketsocket){
- this.socket=socket;
- try{
- in=newDataInputStream(socket.getInputStream());
- out=newDataOutputStream(socket.getOutputStream());
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- publicvoidinitIPs(){//无论是增加还是减少都用此方法来更新在线用户
- StringallIPs="";
- for(inti=0;i<vecIPs.size();i++){//vecIPs至少为1,故不判空
- allIPs=allIPs.concat(vecIPs.get(i));//把ip地址都存放在一个字符串里面
- }
- try{
- for(inti=0;i<vector.size();i++){
- Server.vector.get(i).out.writeUTF(allIPs);//输出信息给每个客户端。
- }
- }catch(IOExceptione1){
- e1.printStackTrace();
- }
- }
- //启动线程时,执行
- publicvoidrun(){
- booleanflag=true;//只是一个标志
- intm;
- //根据当前的在线用户刷新,在线的用户。每个对象只初始化一次!
- initIPs();
- while(flag){
- try{
- Stringmessage=in.readUTF();//输入进来的流,简称输入流,拿到客户端的信息。
- System.out.println("IP是"+socket.getInetAddress().getHostAddress()+"的"+message);//后台打印出来
- if(message.equals("exit")){//如果接收到"exit"字符串说明运行该线程的客户端断开了连接,则需退出该循环,退出线程
- flag=false;//退出循环(指的是本通道关闭,该对象的进程结束)
- //try{
- //Server.vecIPs.remove(this);//从vecIPs中除去本对象的IPs,估计会出错这儿。
- //}catch(NullPointerExceptionee){
- //System.out.println("果然出错");
- //ee.printStackTrace();
- //}
- StringtempIP="add"+socket.getInetAddress().getHostAddress();//把此IP从ip向量表里咔嚓掉
- for(inti=0;i<vecIPs.size();i++){
- if(vecIPs.get(i).equals(tempIP)){
- vecIPs.remove(i);
- break;
- }
- }
- Server.vector.remove(this);//当客户端关闭时,从Vector里除去本对象
- initIPs();//重新初始化各个客户端。
- }else{
- m=Server.vector.size();//返回共有多少个客户端目前。
- for(inti=0;i<m;i++){//给每个客户端发送同样的信息。
- Server.vector.get(i).out.writeUTF(message);//输出信息给每个客户端。
- }
- }
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }
- }
- }
Code:
- //===================MyJFrame2.java===============================
- packagecc.nothing2012.blogServlet;
- importjava.awt.event.ActionEvent;
- importjava.awt.event.ActionListener;
- importjava.awt.event.KeyAdapter;
- importjava.awt.event.KeyEvent;
- importjava.awt.event.WindowAdapter;
- importjava.awt.event.WindowEvent;
- importjava.io.DataInputStream;
- importjava.io.DataOutputStream;
- importjava.io.IOException;
- importjava.net.Socket;
- importjava.net.UnknownHostException;
- importjava.util.Timer;
- importjava.util.TimerTask;
- importjava.util.Vector;
- importjava.util.regex.Matcher;
- importjava.util.regex.Pattern;
- publicclassMyJrame2extendsjavax.swing.JFrameimplementsRunnable{
- publicstaticVector<String>vectorIP=newVector<String>();
- publicstaticVector<String>vectorIPtemp=newVector<String>();
- privateSocketsocket;
- privateDataInputStreamin;
- privateDataOutputStreamout;
- privatebooleanflag=true;//标志如果多个客户端则会出错。
- privatebooleanserverClose=false;//标识服务器端是否关闭,true为关闭,false为没关闭
- privatestaticfinallongserialVersionUID=1L;
- publicMyJrame2(){
- initComponents();//用来初始化界面
- contorClient();//连接服务器等操作
- //this.getRootPane().setDefaultButton(jToggleButton1);
- newTimer().schedule(newTimerTask(){
- publicvoidrun(){
- //for(inti=0;i<vectorIP.size();i++){
- //System.out.println(vectorIP.get(i));
- //}
- //System.out.println(vectorIP.size());
- jList1.setListData(vectorIP);
- }
- },2000,3000);
- }
- publicStringgetMessage(){
- if(!(jTextField2.getText()).equals("")){//如果写的东西不为空
- if(!(jTextField1.getText()).equals("")){//判断是谁写的信息
- return(jTextField1.getText()+":"+jTextField2.getText());
- }else{
- return("默认是骚包:"+jTextField2.getText());//无名氏默认是ClientX
- }
- }else{//什么都没写
- return"";
- }
- }
- publicvoidsetMessage(Stringmessage){
- jTextArea1.append(message+"/n");//添加信息并换行。
- }
- publicvoidcontorClient(){
- try{
- socket=newSocket("xxx.xx.xxx.xxx",55555);//此处新建了一个Socket,并连接服务器
- //。通信从此位置开始。
- jButton1.addActionListener(newActionListener(){//“发送”按钮监听
- publicvoidactionPerformed(ActionEvente){//监听按钮的方法。
- //必须实现的
- //。
- try{
- if(!serverClose){//第一次执行时,默认是开着的。之后,如果服务器开着,
- //即没有关闭,则发送下面内容
- Stringmessage=getMessage();//取得某人写的某些内容
- if(!message.equals("")){
- out=newDataOutputStream(socket
- .getOutputStream());
- out.writeUTF(message);//把message通过s输出去
- jTextField2.setText("");//此处只有发送按钮在监听,
- //故发送之后
- //,内容理应删掉。
- }
- }
- }catch(IOExceptionioe){
- ioe.printStackTrace();
- }
- }
- });
- this.addWindowListener(newWindowAdapter(){//监听客户端是否关闭,如果关闭,
- //则向服务器发送一个
- //“exit”字符串
- publicvoidwindowClosing(WindowEvente){
- try{
- if(serverClose){//serverClose的值一直都是false。
- //此处永远不会被执行。
- }else{//因为监听到了窗口被关闭了。
- out=newDataOutputStream(socket
- .getOutputStream());
- out.writeUTF("exit");//既然关闭了,就发送个信号给服务器。
- //删除该客户端。
- }
- }catch(IOExceptione1){
- e1.printStackTrace();
- }
- }
- });
- //只是实现了enter键的触发而已。
- jTextField2.addKeyListener(newKeyAdapter(){
- publicvoidkeyPressed(KeyEventevent){
- if(event.getKeyCode()==KeyEvent.VK_ENTER){
- try{
- if(!serverClose){//第一次执行时,默认是开着的。之后,如果服务器开着,即没有关闭
- //,则发送下面内容
- Stringmessage=getMessage();//取得某人写的某些内容
- if(!message.equals("")){
- out=newDataOutputStream(socket
- .getOutputStream());
- out.writeUTF(message);//把message通过s输出去
- jTextField2.setText("");//此处只有发送按钮在监听,故发送之后
- //,内容理应删掉。
- }
- }
- }catch(IOExceptionioe){
- ioe.printStackTrace();
- }
- }
- }
- });
- newThread(this).start();//打开一个线程,即执行本类的run()函数。
- }catch(UnknownHostExceptione){
- e.printStackTrace();//打印出错信息而已,别无他意。
- }catch(IOExceptione){
- serverClose=true;
- setMessage("服务器不存在或未打开!");
- }
- }
- privatevoidinitComponents(){
- jLabel1=newjavax.swing.JLabel();
- jTextField1=newjavax.swing.JTextField();
- jLabel2=newjavax.swing.JLabel();
- jScrollPane1=newjavax.swing.JScrollPane();
- jTextArea1=newjavax.swing.JTextArea();
- jTextField2=newjavax.swing.JTextField();
- jButton1=newjavax.swing.JButton();
- jScrollPane2=newjavax.swing.JScrollPane();
- jList1=newjavax.swing.JList();
- setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
- setTitle("八卦聊天器");
- setBackground(newjava.awt.Color(204,204,255));
- jLabel1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
- jLabel1.setText("请输入您的昵称:");
- jTextField1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
- jTextField1.setForeground(newjava.awt.Color(204,204,255));
- jLabel2.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
- jLabel2.setText("在线用户IP:");
- jTextArea1.setColumns(20);
- jTextArea1.setRows(5);
- jScrollPane1.setViewportView(jTextArea1);
- jButton1.setFont(newjava.awt.Font("宋体",0,18));//NOI18N
- jButton1.setText("发送");
- jButton1.addActionListener(newjava.awt.event.ActionListener(){
- publicvoidactionPerformed(java.awt.event.ActionEventevt){
- jButton1ActionPerformed(evt);
- }
- });
- jList1.setModel(newjavax.swing.AbstractListModel(){
- privatestaticfinallongserialVersionUID=1L;
- String[]strings={"Item1","Item2","Item3","Item4","Item5"};
- publicintgetSize(){returnstrings.length;}
- publicObjectgetElementAt(inti){returnstrings[i];}
- });
- jScrollPane2.setViewportView(jList1);
- javax.swing.GroupLayoutlayout=newjavax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(56,56,56)
- .addComponent(jLabel1)
- .addGap(18,18,18)
- .addComponent(jTextField1,javax.swing.GroupLayout.PREFERRED_SIZE,199,javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(layout.createSequentialGroup()
- .addGap(26,26,26)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jTextField2,javax.swing.GroupLayout.PREFERRED_SIZE,440,javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jScrollPane1,javax.swing.GroupLayout.PREFERRED_SIZE,440,javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGap(26,26,26)
- .addComponent(jLabel2))
- .addGroup(layout.createSequentialGroup()
- .addGap(18,18,18)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jButton1,javax.swing.GroupLayout.PREFERRED_SIZE,73,javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jScrollPane2,javax.swing.GroupLayout.PREFERRED_SIZE,152,javax.swing.GroupLayout.PREFERRED_SIZE))))
- .addContainerGap(24,Short.MAX_VALUE))
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(jLabel2,javax.swing.GroupLayout.PREFERRED_SIZE,35,javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING,layout.createSequentialGroup()
- .addGap(44,44,44)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(jLabel1,javax.swing.GroupLayout.PREFERRED_SIZE,40,javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jTextField1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE))))
- .addGap(18,18,18)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,false)
- .addComponent(jScrollPane2)
- .addComponent(jScrollPane1,javax.swing.GroupLayout.DEFAULT_SIZE,402,Short.MAX_VALUE))
- .addGap(18,18,18)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(jTextField2,javax.swing.GroupLayout.PREFERRED_SIZE,63,javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jButton1,javax.swing.GroupLayout.PREFERRED_SIZE,48,javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(39,39,39))
- );
- pack();
- }
- privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt){
- }
- publicvoidrun(){
- System.out.println("MyIPis"
- +socket.getInetAddress().getHostAddress());
- while(flag){
- try{
- in=newDataInputStream(socket.getInputStream());
- if(vectorIPtemp.size()!=0){
- vectorIPtemp.removeAllElements();
- }
- booleanisIPStr=false;
- Stringmessage=in.readUTF();//从服务器发过来的信息
- System.out.println("从服务器获取的信息:"+message);
- //进行匹配看是否有ip地址
- Patternp;
- Matcherm;
- p=Pattern
- .compile("add[0-9]{1,3}//.[0-9]{1,3}//.[0-9]{1,3}//.[0-9]{1,3}");
- m=p.matcher(message);//将信息进行匹配。
- while(m.find()){
- isIPStr=true;//说明是IP字符串。
- Stringmessage2=m.group();//取得类似add222.17.110.117的地址。
- //判断是否只有发送地址而已
- //StringisOnlyIP=message.substring(message2.length());
- //if(!isOnlyIP.equals("")){
- //setMessage(isOnlyIP);//输出到textArea
- //}
- //判断vectorIP中是否已存在该IP了。
- StringIP=message2.substring(3);
- vectorIPtemp.addElement(IP);
- /**由于一下只能判断增加去掉一样的IP的情况,故舍弃*/
- //booleanisExist=false;
- //if(vectorIP!=null){
- //for(inti=0;i<vectorIP.size();i++){
- //if((vectorIP.get(i).equals(IP))){
- ////如果不一样,则继续遍历。如果一样,说明存在改变isExist的值。
- //isExist=true;
- //break;//遍历时,存在就退出。杯具:第一次是自己,存在。而第二个不存在了,且不判断;故出错。
- //}
- //}
- //}
- //if(isExist==false){//不存在就添加
- //vectorIP.addElement(IP);
- //}
- vectorIP.removeAllElements();//先清空,再重新加载。
- }
- //如果执行了while里面的代码,则说明传过来的信息是做IP处理的。
- if(isIPStr==false){
- setMessage(message);
- }else{
- vectorIP=(Vector<String>)vectorIPtemp.clone();//重新赋值给vectorIP
- }
- }catch(IOExceptione){
- serverClose=true;//服务器可能在有客户端存在的时候关闭,此时,客户端输入流会出错,刚执行此处
- setMessage("服务器关闭了!");
- flag=false;//跳出循环
- }
- }
- }
- privatevoidjTextField1ActionPerformed(java.awt.event.ActionEventevt){
- //
- }
- privatevoidjTextField2ActionPerformed(java.awt.event.ActionEventevt){
- //
- }
- publicstaticvoidmain(Stringargs[]){
- newMyJrame2().setVisible(true);
- }
- privatejavax.swing.JButtonjButton1;
- privatejavax.swing.JLabeljLabel1;
- privatejavax.swing.JLabeljLabel2;
- privatejavax.swing.JListjList1;
- privatejavax.swing.JScrollPanejScrollPane1;
- privatejavax.swing.JScrollPanejScrollPane2;
- privatejavax.swing.JTextAreajTextArea1;
- privatejavax.swing.JTextFieldjTextField1;
- privatejavax.swing.JTextFieldjTextField2;
- }
==================
有个很明显的漏洞可以修改在线IP。不过也有个很好的解决方法,那就是在客户端先对信息进行匹配处理。
最后张图:
发表评论
-
Singletons and lazy loading
2011-09-26 19:47 914The Java Memory Model # ... -
JVM blogs
2011-09-14 21:40 470话说是 【JVM详解的专题】,很多文章的差不多的,有的详 ... -
effective Java _Generic
2011-09-12 12:03 0#23 -
Class Loader
2011-08-28 16:47 774专栏合集(一):Java深度历险 pdf已上传1 ... -
Study Linkinginginginginginginging
2011-08-27 10:42 730#1 java 工程和类等路径汇总 #2 让Apac ... -
How to send Email
2011-08-26 15:32 6021.java mail 使用介绍 2.Java ... -
Java_Try_Finally
2011-07-18 11:51 643public class TestTryCatch { ... -
Java Class ClassLoader
2011-07-15 17:05 1027下午在看《Java 深度历险》,对Class & ... -
关键字 final & transient
2011-06-08 16:49 965final 详见: http://java.chinaitl ... -
课程设计3
2010-01-04 14:09 779题目3:动态分区式存储管理的存储分配和回收 一、设计目的 ... -
课程设计1
2010-01-04 14:24 748采用的是C++语言编写的,但PCB的数据结构是符合要求的。 ... -
os课程设计后感
2010-01-04 14:48 541今天终于把操作系统的实验给终结了。基本要求算是符合了,可能表 ... -
java作业01
2010-03-06 16:02 663package homework01; public cla ... -
Java作业02
2010-03-11 14:22 789package homework02; import jav ... -
File函数返回当前路径
2010-03-12 19:37 671package netWorkMoreThreadCopy; ... -
多线程文件复制(界面)1
2010-03-12 23:45 940package netWorkMoreThreadCopy; ... -
Java IO 转摘
2010-03-15 00:26 510java中的io中的(input/output)str ... -
java作业03
2010-03-17 00:59 696package homework03; import jav ... -
Java作业
2010-03-17 01:19 640package homework03;import java. ... -
java作業3
2010-03-18 18:36 592package homework03;/** 首先编写一个抽象 ...
相关推荐
在这个“socket群聊实例”中,我们将探讨如何使用Java的Socket和ServerSocket类构建一个简单的多人聊天系统。 首先,服务器端的实现至关重要。`ServerSocket`类在Java中用于监听客户端的连接请求。你需要创建一个`...
本项目以"socket编程(实现群聊功能+界面清晰)"为主题,旨在创建一个支持多客户端实时交流的群聊系统,同时提供了图形用户界面(GUI)以提高用户体验。以下是关于这个项目的一些关键知识点和实现细节: 1. **...
"Socket群聊"项目就是利用Socket来构建一个可以支持多用户同时在线聊天的应用。在这个项目中,观察者模式(Observer Pattern)被巧妙地融入,以处理用户间的实时消息传递和状态更新。 首先,我们需要理解Socket的...
本项目标题为"socket单聊 群聊 发送文件",这意味着它利用Java的Socket库构建了一个具备基本聊天功能的应用,包括一对一的单聊、多用户参与的群聊以及文件传输。下面将详细介绍这些知识点: 1. **Java Socket**: ...
socket通信,类似于群聊效果的客户端代码。
网页群聊源代码是一种实现在线多人聊天功能的技术方案,它基于Web技术,允许用户通过浏览器进行实时交流。这种代码通常由HTML、CSS和JavaScript等前端技术构建,有时也会结合服务器端语言如PHP、Node.js或Python来...
Socket局域网群聊是一个基于C#编程语言和WPF(Windows Presentation Foundation)技术实现的多客户端通信系统,它利用了Socket技术构建了一个简单的聊天服务器,使得多个客户端可以在同一个局域网内进行实时的消息...
`express_socket_demo`是一个基于Express和Socket.IO的示例项目,它演示了如何在Web应用中实现群聊功能。Express是Node.js中广泛使用的Web框架,而Socket.IO则是一个强大的库,用于实现实时双向通信。下面我们将详细...
1、支持群聊,server负责转发,可连接多个client 2、附带.bat启动程序,server.bat启动服务(可修改server.bat,改变服务端口号) 3、client.bat启动客户端(可修改client.bat,设置服务端ip和端口号) 注:需安装...
研究了一个多星期socket 写了个局域网群聊的小程序,, 分服务端,,,客户端(可多开),,,代码比较乱,但有注释, 给大家看看有什么不足的地方 告诉小弟我,,qq623932737 email:623932737@qq.com
【标题】"群聊源代码"揭示了这是一个关于创建群聊功能的软件开发项目,使用的编程语言是VB.NET。VB.NET(Visual Basic .NET)是微软公司推出的一种面向对象的编程语言,它是.NET框架的一部分,提供了丰富的库和工具...
LINUX下基于socket和多线程的聊天程序设计与实现的群聊客户端关键代码
在这个“socket+swing局域网群聊系统”项目中,我们看到这两个技术的结合,为初学者提供了一个很好的实践平台。 首先,让我们详细了解一下Socket编程。Socket是网络编程的基础,它提供了应用程序之间通信的端点。在...
Socket网络编程是计算机网络通信中的基础...在这个“Socket网络编程实例”中,通过分析和理解SocketServer的代码,我们可以深入学习Socket通信的原理和实践,掌握网络编程的基础,并为构建更复杂的分布式系统打下基础。
在本示例中,"socket编程实现简单私聊群聊源码" 涉及到的是如何使用Socket来构建一个基本的聊天应用程序,包括一对一的私聊和多用户参与的群聊功能。 首先,Socket是操作系统提供的接口,它允许应用程序通过网络...
项目中的"SocketTest"可能是测试代码或者主程序入口,可能包含了服务器端和客户端的启动逻辑,以及必要的异常处理和日志记录。在实际开发中,我们还需要考虑安全性、性能优化、错误恢复等方面的问题,以确保软件的...
文章目录一、动图效果展示二、服务端代码(核心)三、bug吐槽四、分享交流 一、动图效果展示 二、服务端代码(核心) 光说不练歪把子 package socket_study03; import java.io.DataInputStream; import java.io....
源码中应该有异常捕获和日志打印的代码。 10. **数据持久化**:为了保存聊天记录,应用可能会使用SQLite数据库或Shared Preferences存储本地数据。当用户退出应用后,这些记录仍能保留。 通过分析和学习这个...
1. **网络通信**:C#提供了System.Net命名空间,包含用于网络编程的各种类,如Socket、TcpClient和TcpListener。开发者可能使用这些类来建立客户端和服务器之间的连接,实现数据的实时传输。 2. **多线程**:为了...
在提供的压缩包文件“基于JAVA网络编程的模拟群聊系统源码”中,可以找到实现这些功能的具体代码。通过分析和学习这些源码,开发者可以深入了解Java网络编程和多线程应用的实践方法,为进一步开发更复杂的分布式系统...