关闭

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

标签: 聊天工具variablessocketthreadstring
913人阅读 评论(1) 收藏 举报
分类:

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

}

}


}











  






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8510次
    • 积分:143
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:1篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论