通过线程处理来自客户端或者服务端的信息,实现了一对一以及多对一的效果,也就是服务端可以同时接收来自多方的客户端的信息,四个页面,分别是服务端的UI和Thread线程,还有客户端的UI和线程,服务端是本机~~~

/*

* ServerUI.java
 *
 * Created on __DATE__, __TIME__
 */
package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.DefaultListModel;

/**
 *
 * @author  __USER__
 */
public class ServerUI extends javax.swing.JFrame {

final DefaultListModel dlm = new DefaultListModel();
HashMap<String, ClientBean> clientMap = new HashMap<String, ClientBean>(); //clientBean里面包含client的所有基本信息
protected int i;

/** Creates new form ServerUI */
public ServerUI() {
initComponents();
startServer();

jListClient.setModel(dlm);

}
private String readName(Socket client){
//读取登陆状态的客户端的姓名
String name=null;

try {
BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream(),"GBK"));
String line=br.readLine();
if(line!=null){
name=line;
}
Thread.sleep(1000);

} catch (InterruptedException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();

}
return name;

}
private void startServer() {
// 启动服务端,将登陆状态的客户端的信息显示在服务端的界面
Thread t = new Thread() {

public void run() {
try {
ServerSocket server = new ServerSocket(12345);
while (true) {
Socket client = server.accept();
String ip = new String(client.getInetAddress()
.getHostAddress()); //获取客户端登陆的Ip

String name=readName(client);

ClientBean clientBean = new ClientBean();
clientBean.setIp(ip);
clientBean.setName(name);
clientBean.setSocket(client);
clientMap.put(ip, clientBean);
dlm.addElement(clientBean);
ServerThread st = new ServerThread(client,
jTextAreaMsg1);
Thread t = new Thread(st);
t.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();

Thread heartBeat = new Thread() {
@Override
public void run() {
try {
//不断轮询查看客户端的连接状态,连接还是断开
while (true) {
Iterator<String> it = clientMap.keySet().iterator(); //key是String类型
while (it.hasNext()) { //it.hasNext是判断是否后面还有,如果有就继续运行下去,若没有记终止循环
String key = it.next(); //it.next是获取它的下一个数据,将其保存在key里,
ClientBean cb = clientMap.get(key);
try {
cb.getSocket().sendUrgentData(0XFF);

} catch (Exception e) {
//有异常,说明已经断开
System.out.println("客户端已断开");

//1、clientMap将断开的客户端移除掉
clientMap.remove(key);
//2、界面上也删除
for(int i=0;i<dlm.getSize();i++){
ClientBean clientBean=(ClientBean)dlm.getElementAt(i);
if(clientBean.getIp().equals(key)){
dlm.removeElement(clientBean);
}
}

}

}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}

}
};
heartBeat.start();

}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
//GEN-BEGIN:initComponents
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();
jTextAreaMsg1 = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
jTextAreaMsg2 = new javax.swing.JTextArea();
jButtonSend = new javax.swing.JButton();
jScrollPane3 = new javax.swing.JScrollPane();
jListClient = new javax.swing.JList();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("\u670d\u52a1\u7aef");

jTextAreaMsg1.setBackground(new java.awt.Color(204, 255, 255));
jTextAreaMsg1.setColumns(20);
jTextAreaMsg1.setRows(5);
jScrollPane1.setViewportView(jTextAreaMsg1);

jTextAreaMsg2.setBackground(new java.awt.Color(204, 255, 255));
jTextAreaMsg2.setColumns(20);
jTextAreaMsg2.setRows(5);
jScrollPane2.setViewportView(jTextAreaMsg2);

jButtonSend.setBackground(new java.awt.Color(204, 255, 255));
jButtonSend.setFont(new java.awt.Font("隶书", 0, 18));
jButtonSend.setForeground(new java.awt.Color(255, 51, 255));
jButtonSend.setText("\u53d1\u9001");
jButtonSend.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonSendActionPerformed(evt);
}
});

jListClient.setBackground(new java.awt.Color(204, 255, 255));
jListClient.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "192.168.9.236", "192.168.9.235",
"192.168.9.234", "192.168.9.233", "192.168.9.237" };

public int getSize() {
return strings.length;
}

public Object getElementAt(int i) {
return strings[i];
}
});
jScrollPane3.setViewportView(jListClient);

javax.swing.GroupLayout layout = new javax.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(
javax.swing.GroupLayout.Alignment.TRAILING,
layout
.createSequentialGroup()
.addComponent(
jScrollPane3,
javax.swing.GroupLayout.PREFERRED_SIZE,
108,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(
layout
.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(
jScrollPane1,
javax.swing.GroupLayout.DEFAULT_SIZE,
346,
Short.MAX_VALUE)
.addComponent(
jScrollPane2,
javax.swing.GroupLayout.DEFAULT_SIZE,
346,
Short.MAX_VALUE)))
.addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout
.createSequentialGroup()
.addContainerGap(
381,
Short.MAX_VALUE)
.addComponent(
jButtonSend,
javax.swing.GroupLayout.PREFERRED_SIZE,
81,
javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap()));
layout
.setVerticalGroup(layout
.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(
layout
.createSequentialGroup()
.addContainerGap()
.addGroup(
layout
.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(
jScrollPane3,
javax.swing.GroupLayout.PREFERRED_SIZE,
285,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(
layout
.createSequentialGroup()
.addComponent(
jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE,
182,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(
jScrollPane2,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
javax.swing.LayoutStyle.ComponentPlacement.RELATED,
45,
Short.MAX_VALUE)
.addComponent(
jButtonSend,
javax.swing.GroupLayout.PREFERRED_SIZE,
55,
javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap()));

pack();
}// </editor-fold>
//GEN-END:initComponents

private void jButtonSendActionPerformed(java.awt.event.ActionEvent evt) {
//向客户端发送消息
Object[] selectedClients = (Object[])jListClient.getSelectedValues();
for (Object object : selectedClients) {
try {
ClientBean clientBean=(ClientBean)object;
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientMap.get(clientBean.getIp()).getSocket().getOutputStream(), "GBK"));
bw.write(jTextAreaMsg2.getText() + "\n");
bw.flush();
          jTextAreaMsg2.setText(null);
} catch (UnsupportedEncodingException e) {

e.printStackTrace();
} catch (IOException e) {

e.printStackTrace();
}
}

}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ServerUI().setVisible(true);
}
});
}

//GEN-BEGIN:variables
// Variables declaration - do not modify
private javax.swing.JButton jButtonSend;
private javax.swing.JList jListClient;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JTextArea jTextAreaMsg1;
private javax.swing.JTextArea jTextAreaMsg2;
// End of variables declaration//GEN-END:variables

}

//serverThread用线程来处理来自客户端的信息

package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.SocketException;
import javax.swing.JTextArea;

public class ServerThread implements Runnable{
private Socket client=null;
private JTextArea msgList=null;
public ServerThread(Socket client,JTextArea msgList){
this.client=client;
this.msgList=msgList;

}
public void run(){
//获取客户端的信息
while(true){
try {
BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream(),"GBK"));
try {
client.sendUrgentData(0XFF);
} catch (Exception e) {
break;
}
String line=br.readLine();
if(line!=null){
msgList.setText(msgList.getText()+line+"\n");
}
Thread.sleep(1000);
}catch(SocketException e){
break;

} catch (InterruptedException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();

}

}

}
}

/*
 * ClientUI.java
 *
 * Created on __DATE__, __TIME__
 */

package socket;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.JList;
import javax.swing.JOptionPane;

/**
 *
 * @author  __USER__
 */
public class ClientUI extends javax.swing.JFrame {
private Socket client = null;

/** Creates new form ClientUI */
public ClientUI() {
initComponents();
connectServer();
sendClientName();
startClientThread();
}

private void sendClientName() {
//将登陆上的用户的名字传给服务端
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
client.getOutputStream(), "GBK"));
bw.write("睢雨亭" + "\n");
bw.flush();
jTextAreaMsg4.setText(null);

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

private void startClientThread() {
// 启动客户端的线程
ClientThread ct = new ClientThread(client, jTextAreaMsg3);
Thread t = new Thread(ct);
t.start();
}

private void connectServer() {
// 连接服务端
try {
client = new Socket("192.168.9.236", 12345);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
//GEN-BEGIN:initComponents
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();
jTextAreaMsg3 = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
jTextAreaMsg4 = new javax.swing.JTextArea();
jButtonSend = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("\u5ba2\u6237\u7aef");
setBackground(new java.awt.Color(255, 255, 255));

jTextAreaMsg3.setBackground(new java.awt.Color(204, 255, 255));
jTextAreaMsg3.setColumns(20);
jTextAreaMsg3.setRows(5);
jScrollPane1.setViewportView(jTextAreaMsg3);
jTextAreaMsg4.setBackground(new java.awt.Color(204, 255, 255));
jTextAreaMsg4.setColumns(20);
jTextAreaMsg4.setRows(5);
jScrollPane2.setViewportView(jTextAreaMsg4);
jButtonSend.setBackground(new java.awt.Color(204, 255, 255));
jButtonSend.setFont(new java.awt.Font("隶书", 0, 18));
jButtonSend.setForeground(new java.awt.Color(255, 0, 255));
jButtonSend.setText("\u53d1\u9001");
jButtonSend.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonSendActionPerformed(evt);
}
});

javax.swing.GroupLayout layout = new javax.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()
.addContainerGap()
.addGroup(
layout
.createParallelGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
false)
.addComponent(
jScrollPane2,
javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(
jScrollPane1,
javax.swing.GroupLayout.Alignment.LEADING,
javax.swing.GroupLayout.DEFAULT_SIZE,
274,
Short.MAX_VALUE)))
.addGroup(
javax.swing.GroupLayout.Alignment.TRAILING,
layout
.createSequentialGroup()
.addGap(
294,
294,
294)
.addComponent(
jButtonSend,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)))
.addContainerGap()));
layout.setVerticalGroup(layout.createParallelGroup(
javax.swing.GroupLayout.Alignment.LEADING).addGroup(
layout.createSequentialGroup().addContainerGap().addComponent(
jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE,
225, javax.swing.GroupLayout.PREFERRED_SIZE).addGap(18,
18, 18).addComponent(jScrollPane2,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE).addGap(18, 18,
18).addComponent(jButtonSend,
javax.swing.GroupLayout.PREFERRED_SIZE, 46,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)));

pack();
}// </editor-fold>
//GEN-END:initComponents

private void jButtonSendActionPerformed(java.awt.event.ActionEvent evt) {
//得到socket的输出流,并获取对应的信息
if (client == null) {
JOptionPane.showMessageDialog(this, "未成功连接服务器");
return;

}

//正确发送消息的情况
try {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
client.getOutputStream(), "GBK"));
bw.write(jTextAreaMsg4.getText() + "\n");
bw.flush();
jTextAreaMsg4.setText(null);

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ClientUI().setVisible(true);
}
});
}

//GEN-BEGIN:variables
// Variables declaration - do not modify
private javax.swing.JButton jButtonSend;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextAreaMsg3;
private javax.swing.JTextArea jTextAreaMsg4;
// End of variables declaration//GEN-END:variables

}

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import javax.swing.JTextArea;

public class ClientThread implements Runnable{
private Socket socket=null;
private JTextArea msgList=null;

public ClientThread(Socket socket,JTextArea msgList){
this.socket=socket;
this.msgList=msgList;
}

@Override

public void run() {
//接收来自服务端的信息
while(true){
BufferedReader br=null;
String line=null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"GBK"));
line = br.readLine();
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}

if(line!=null){
msgList.setText(msgList.getText()+line+"\n");
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

}

仿扣扣聊天工具(实现多对一)相关推荐

  1. Java+Swing+mysql仿QQ聊天工具

    Java+Swing+mysql仿QQ聊天工具 一.系统介绍 二.功能展示 1.用户登陆 2.好友列表 3.好友聊天 4.服务器日志 三.系统实现 四.其它 1.其他系统实现 2.获取源码 一.系统介 ...

  2. Java实现仿QQ聊天工具的项目总结

    在写这篇文章之前,首先要感谢我的队友的辛勤付出,没有他们的付出与配合,这个项目是不能顺利完成的. 资源文件:工程文件,可运行JAR包 第一点 经验:项目开始之前应该先向老师或者学长先询问经验.或者到网 ...

  3. 仿QQ聊天工具(Android源码)

    2019独角兽企业重金招聘Python工程师标准>>> QQ给人感觉界面很简洁大气, 但如果要自己实现QQ的界面的话,难度还是不小的, 小编经过数日鏖战,实现了类似QQ登录和聊天界面 ...

  4. 仿qq聊天工具源码(含服务器端、客户端以及数据库脚本)

    [实例简介]完成许多功能,发送图片文字 文件等,1v1聊天等等 加好友 删除好友 等等 文件:590m.com/f/25127180-488579115-c94ffd(访问密码:551685) [实例 ...

  5. socket仿qq聊天工具(一)(扩展博客)

    这个项目主要是实现类似qq的一对一聊天和群聊天. 首先对于qq来说腾讯那边的服务器肯定是一直开着的,这样大家才可以登录的上去,登录上去以后会刷新你的好友列表.这样你才可以看到好友的信息,就是你拥有哪些 ...

  6. [源码和文档分享]基于java 的仿QQ聊天工具

    一 需求分析 本系统是基于java开发的聊天室.有用户注册.用户登陆.修改密码.忘记密码.添加好友.用户聊天.群聊功能.如果服务器还没有启动,则客户端是不可以登陆.注册.忘记密码,如果在运行过程中,服 ...

  7. 仿QQ聊天工具(JAVA实现)项目总结

    闲暇之余基于Java Swing自己写了一个即时聊天软件LL,源码地址:https://github.com/nmyphp/msn532.git.欢迎大家一起改进. 一.遇到的异常及解决办法 1.   ...

  8. java 仿qq 聊天工具(基于mvc三层架构,附 mvc架构模式pdf说明文档)支持开源

    用了3天多时间,因实验5要求就顺便做一下这东西吧,废话不多说,就简单说一些东西吧: 该聊天系统是基本mvc模式设计的(感觉这种模式代码比较好管理,可扩展性强),编写过程中涉及的东西比较多,包括对象实例 ...

  9. 基于java 的仿QQ聊天工具

    概要设计 在客户端:当用户登录后,生成唯一的socket, 存放在Client实体类中,在整个客户端就一个Client类和一个socket.有一个窗口控制器--ChatUIList,用来记录用户和好友 ...

最新文章

  1. SQL语句技巧:查询时巧用OR实现逻辑判断
  2. 学习JNI一些基础知识
  3. mysql 2048kb限制_如何解决phpmyadmin导入数据库文件最大限制2048KB
  4. SAP 凭证冲销可以使用BAPI_ACC_DOCUMENT_REV_POST或者BDC录制FB08来做
  5. java 文件上传ssm_ssm框架下实现文件上传
  6. java原子操作cas_java并发编程系列二:原子操作/CAS
  7. opencv 直方图_OpenCV-Python 直方图-3:二维直方图 | 二十八
  8. python getsize_Python getsizeof()和getsize()区分详解
  9. 抛弃百度UMEditor,拥抱summernote (解决上传文件又慢又卡的问题)
  10. redis客户端分析
  11. 有的编译器,for (i=1; i 《 1; i++)会执行循环体
  12. 四川大学软件学院操作系统笔记
  13. IDEA创建JSP项目
  14. mac html flash,苹果电脑flash过期无法打开网页的解决方法
  15. 在kitti数据集与nsh_indoor_outdoor.bag,自己数据集(RS_16)上运行LeGo-LOAM
  16. iMeta | 俄亥俄州立大学郑庆飞组发表多组学方法研究肿瘤微生物组综述
  17. 如何发现Synaptics病毒
  18. word2vec 中的数学原理详解(六)若干源码细节
  19. 怎么理解无界队列和有界队列
  20. 如何靠代码发家致富?——10种可以赚钱的途径

热门文章

  1. 推荐:在线面试实时编程工具——ShowMeBug
  2. Excel-批量生成超链接HYPERLINK
  3. maven-setting
  4. ArcGIS Pro 去除Landsat7导出影像坏条带过程及后续简单处理
  5. 几何画板教程:几何画板功能知多少?
  6. macbook pro 盒盖后不休眠的问题
  7. 29岁才转行软件测试,目前31了,我的一些经历跟感受(完)
  8. 每月一书(2021010):《苏世民:我的经验与教训》
  9. oracle容灾架构头脑风暴
  10. mysql 英文文献_mysql数据库英文文献.doc