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

原创 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
  • 下载

[分享] Wex5 作品 仿微信聊天工具 部分代码 详情 留下邮箱

wex5作品,仿微信聊天工具,部分代码详情,留下邮箱,话不多,看效果 1 QQ截图20151130144646.png (77.89 KB, 下载次数:...

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

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

c#基于udp实现的p2p语音聊天工具

原创性申明 此博文的出处 为 http://blog.csdn.net/zhujunxxxxx/article/details/39251241如果进行转载请注明出处。本文作者原创,邮箱zhujunx...

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

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

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

本demo非常简单并,没有用到数据库来存储数据而是Cach来缓存数据,后台代码: public class _6_1 : IHttpHandler { public...
  • dz45693
  • dz45693
  • 2011年12月09日 09:35
  • 2716

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

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

Android Socket 聊天工具(一个服务端实现多个客户端间通信)

程序开源,共同学习。最近在学Android,做了一个由Socket实现的基于TCP协议的聊天工具,用一个服务端支持多个客户端之间的交流 通信。虽然本人之前做过蓝牙控制小车的软件,但这次做起来也花了不少...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:仿扣扣聊天工具(实现多对一)
举报原因:
原因补充:

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