群聊和指定对象的聊天实现
1注意声明为全局变量否则出现空指针
2实现服务器的多连接
ArrayList sockets =new ArrayList<> ();
3防止断开连接出错,把每个连接用新的线程
new Thread(new Runnable() {
>@Override
public void run() {
try {
System.out.println("服务器启动");
server = new ServerSocket(8080);
sockets = new ArrayList<>();
while (isRunning) {
socket = server.accept();
Thread t = new Thread(new ServerRead(MyServer.this, socket));
t.start();
System.out.println("有客户端连接");
}
} catch (IOException e1) {
e1.printStackTrace();
}}}).start();
package com.chatOKJSON.android;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import net.sf.json.JSONObject;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.awt.event.ActionEvent;
import javax.swing.JList;
import javax.swing.JTextField;
public class MyServer extends JFrame {
private JPanel contentPane;
private ServerSocket server;
private Socket socket;
private JTextArea textArea;
private OutputStream os;
private InputStream is;
public boolean isRunning = true;
public DefaultListModel<String> model;
public JList list;
public HashMap<String, Socket> sockets;
public boolean isRunning() {
return isRunning;
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyServer frame = new MyServer();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
*
* @param 此方法读
*/
public void readLine(String line) {
System.out.println("开始解析这个信息"+line);
JSONObject obj=JSONObject.fromObject(line);
String type=obj.getString("type");
if(type.equals("toSingle")){
String msg=obj.getString("message");
String to=obj.getString("to");
String from=obj.getString("from");
String time=obj.getString("time");
Socket toSocket=sockets.get(to);
System.out.println(toSocket.getInetAddress().getHostAddress());
OutputStream os;
try {
os = toSocket.getOutputStream();
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
bw.write(msg+"\n");
bw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
model.addElement(line);
}
/**
* Create the frame.
*/
public MyServer() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnNewButton = new JButton("启动服务器");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//此线程等待客户端连接
new Thread(new Runnable() {//匿名内部类
@Override
public void run() {
try {
System.out.println("服务器启动");
server = new ServerSocket(8080);
sockets = new HashMap();
while (isRunning) {
socket = server.accept();
//每一个客户端对应一个线程
Thread t = new Thread(new ServerRead(MyServer.this, socket));
t.start();
sockets.put(socket.getInetAddress().getHostAddress(), socket);
System.out.println("有客户端连接");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}).start();
}
});
btnNewButton.setBounds(278, 10, 128, 77);
contentPane.add(btnNewButton);
textArea = new JTextArea();
textArea.setBounds(22, 167, 241, 69);
contentPane.add(textArea);
JButton btnNewButton_1 = new JButton("发送");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
write();
}
});
btnNewButton_1.setBounds(273, 167, 112, 69);
contentPane.add(btnNewButton_1);
list = new JList();
model = new DefaultListModel<>();
list.setModel(model);
list.setBounds(23, 10, 241, 149);
contentPane.add(list);
}
public void read(Socket socket) {
if (socket.isConnected()) {// boolean isConnected() 返回套接字的连接状态。
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
model.addElement(InetAddress.getLocalHost().getHostName()+""+line);
System.out.println("服务器收到:" + line);
} catch (IOException e) {
e.printStackTrace();
}
}else{
sockets.remove(socket);
}
}
public void write() {
try {Set<String>set=sockets.keySet();
Iterator<String>it=set.iterator();
while(it.hasNext()){
OutputStream os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
String words = textArea.getText();
System.out.println("服务器发送信息");
bw.write(words + "\n");
bw.flush();
}
textArea.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
}
**********************************************
package com.chatOKJSON.android;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerRead implements Runnable {
private MyServer server;
private Socket socket;
public ServerRead(MyServer server, Socket socket) {
this.server = server;
this.socket = socket;
}
@Override
public void run() {
InputStream is;
try {
is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while (server.isRunning()) {// 别忘记方法的括号
String line = br.readLine();
server.readLine(line);
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
****************************************************
package com.chatOKJSON.android;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import net.sf.json.JSONObject;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JList;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;
public class MyClient extends JFrame {
private JPanel contentPane;
private Socket socket;
private JTextArea textArea;
private DefaultListModel<String> modle;
private boolean isRunning=true;
private JList list;
private String message;
private String toIP;
private JTextField textField;
public boolean isRunning(){
return isRunning;
}
/**
*
* @return生成JSON格式的信息,返回要发送信息
*/
public String creatMessage(){
message=textArea.getText();
toIP=textField.getText();
//String message=textArea.getText();
JSONObject obj=new JSONObject();
obj.put("message", message);
obj.put("type", "toSingle");
//得到时间Data data=new DAta();data.getTime();
Calendar calendar=Calendar.getInstance();//距1970的毫秒数
long time=calendar.getTimeInMillis();
obj.put("time", ""+time);
obj.put("from", socket.getInetAddress().getHostAddress());
obj.put("to", toIP);
System.out.println(obj.toString());
return obj.toString();
}
/**
* 将信息发送给服务器
* msg即为要发送信息
*/
public void write(String msg){//穿入要发送信息
try {
OutputStream os=socket.getOutputStream();
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
bw.write(msg+"\n");
modle.addElement(message);//聊天窗口添加消息
textArea.setText("");//消息窗口清空
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyClient frame = new MyClient();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MyClient() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
textField = new JTextField();
textField.setBounds(308, 137, 99, 52);
contentPane.add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("发送");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//String toIP =textField.getText();
String msg=creatMessage();
write(msg);
}
});
btnNewButton.setBounds(308, 200, 116, 38);
contentPane.add(btnNewButton);
list = new JList();
// JScrollPane scrollPane = new JScrollPane(list);
list.setBounds(28, 10, 252, 179);
modle=new DefaultListModel<>(); //
list.setModel(modle); //
contentPane.add(list);
JButton btnNewButton_1 = new JButton("连接服务器");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {System.out.println("连接服务器");
socket=new Socket("192.168.0.64", 8080);
System.out.println("连接完成");
//此线程
Thread t=new Thread(new ClientRead(MyClient.this));
t.start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
btnNewButton_1.setBounds(308, 28, 99, 60);
contentPane.add(btnNewButton_1);
textArea = new JTextArea();//错误:JTextArea textArea = new JTextArea();
textArea.setBounds(28, 208, 252, 44);
contentPane.add(textArea);
}
public void read(){
try {
InputStream is =socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String line=br.readLine();
modle.addElement("服务器说的"+line);
System.out.println("服务器:"+line);
} catch (IOException e) {
e.printStackTrace();
}
}
}
***********************************************
package com.chatOKJSON.android;
public class ClientRead implements Runnable {
private MyClient client;
public ClientRead(MyClient client) {
this.client = client;
}
@Override
public void run() {
while (client.isRunning()) {
client.read();
}
}
}