ServerSocket 、Socket 创建Java服务器与客户端以JSON格式聊天
2015-08-06 12:00
633 查看
群聊和指定对象的聊天实现
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(); } } }
相关文章推荐
- Spring(二):异常
- Eclipse下BASE64Decoder提示错误的解决办法
- 二叉树遍历的非递归实现 java版本
- Java工厂模式
- java中的基本类型
- Spring使用SLF4J代替Commons Logging写日志
- MyEclipse点部署没有反应
- ubuntu下创建eclipse的快捷方式
- java单利模式
- java获取系统的版本号
- JavaWeb学习之Filter
- 解决Spring TestContext下运行JUnit4抛错(java.lang.NoClassDefFoundError)的问题
- Java代理模式
- 统计项目下Java文件数及代码行数
- springTest 测试service dao
- eclipse一闪而过 启动失败
- java中的域、字段是什么?
- 详解Java编程中的策略模式
- <context annotation-config />标签意义:
- java中形参,实参改变