仿扣扣聊天工具(实现多对一)

原创 2012年03月30日 09:23:58

通过线程处理来自客户端或者服务端的信息,实现了一对一以及多对一的效果,也就是服务端可以同时接收来自多方的客户端的信息,四个页面,分别是服务端的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();
}

}

}


}











  






版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

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

一、遇到的异常及解决办法 1.        org.hibernate.HibernateException:Could not parse configuration: /hibernate.c...

仿扣扣聊天demo

  • 2014-05-07 17:32
  • 315KB
  • 下载

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

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

仿webqq做的一个webos桌面效果,Jquery结合WCF开发的非常优秀的网页聊天工具

QQ技术交流群:159995692 /--------   临时开放的测试       帐号/密码:[88888888/1;666666/1]   &#...

Android 开发即时聊天工具 YQ :(三) 实现登陆功能

http://www.2cto.com/kf/201210/159442.html 前面socket基本通信完了,登陆界面也已经完成,下面就是重点了,实现登陆功能 服务器和客户端的...

Android 开发即时聊天工具 YQ :(三) 实现登陆功能

前面socket基本通信完了,登陆界面也已经完成,下面就是重点了,实现登陆功能 服务器和客户端的代码当然不肯能用那个控制台的那个了,所以全部得重写,不过原理都一样,代码也差不多,都有注释,一看就明白...

Socket应用,简单聊天工具实现

这是一个使用Java实现,使用Socket技术实现的简单的聊天工具 并且使用了简单的IO技术。

jquery+asp.net实现的一个简易web聊天工具

本demo非常简单并,没有用到数据库来存储数据而是Cach来缓存数据,后台代码: public class _6_1 : IHttpHandler { public...

SQLite DBRecovery 恢复引擎实现微信等一些手机聊天工具删除记录的快速恢复

SQLite DBRecovery 恢复引擎提供了对开源嵌入式数据库SQLite的数据库损毁数据恢复功能,能够快速恢复SQLite 数据库意外操作、系统故障、文件损坏以及误删除记录等原因导致的数据记录...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)