赞
踩
打算在微信公众号记录比较好,csdn不定时记录,有兴趣可以逛逛
最近学习了Java的net包,看了网上的开源代码,整理了一部分服务端代码,实现了消息监听,直接上代码。
一。新建了一个消息类,用于存储消息进行传输
- package com.xing.studyTest.net.im.model;
-
- import java.io.Serializable;
- import java.util.HashMap;
- import java.util.HashSet;
-
- /**
- * 消息信息
- * @author xinghua
- *
- */
- public class MessageBean implements Serializable{
-
- private static final long serialVersionUID = 1L;
- private int type; // 1私聊 0上下线更新 -1下线请求 2请求发送文件 3.确定接收文件
- private HashSet<String> clients; // 存放选中的客户
- private HashSet<String> to;//
- public HashMap<String, MessageBean> onlines;//
- private String info;//信息
- private String timer;//时间
- private String name;//昵称
- private String fileName;//文件名
- private int size;//文件大小
- private String ip;//IP
- private int port;//端口
-
- public int getSize() {
- return size;
- }
-
- public void setSize(int size) {
- this.size = size;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public HashSet<String> getTo() {
- return to;
- }
-
- public void setTo(HashSet<String> to) {
- this.to = to;
- }
-
- public int getType() {
- return type;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
- public HashSet<String> getClients() {
- return clients;
- }
-
- public void setClients(HashSet<String> clients) {
- this.clients = clients;
- }
-
- public String getInfo() {
- return info;
- }
-
- public void setInfo(String info) {
- this.info = info;
- }
-
- public String getTimer() {
- return timer;
- }
-
- public void setTimer(String timer) {
- this.timer = timer;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getIp() {
- return ip;
- }
-
- public void setIp(String ip) {
- this.ip = ip;
- }
-
- public int getPort() {
- return port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public HashMap<String, MessageBean> getOnlines() {
- return onlines;
- }
-
- public void setOnlines(HashMap<String, MessageBean> onlines) {
- this.onlines = onlines;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return " [type=" + type + ", clients=" + clients + ", to=" + to + ", onlines=" + onlines + ", info="
- + info + ", timer=" + timer + ", name=" + name + ", fileName=" + fileName + ", size=" + size + ", ip="
- + ip + ", port=" + port + "]";
- }
-
- }
二、因为要存储在线用户和用户连接信息,所以还需要个实体类
- package com.xing.studyTest.net.im.model;
-
- import java.io.Serializable;
- import java.net.Socket;
-
- /**
- * 连接信息
- * @author xinghua
- *
- */
- public class SocketBean implements Serializable{
-
- private static final long serialVersionUID = 1L;
- private String name;//名称
- private Socket socket;//socket
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Socket getSocket() {
- return socket;
- }
-
- public void setSocket(Socket socket) {
- this.socket = socket;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "ServerBean [name=" + name + ", socket=" + socket + "]";
- }
-
-
- }
三,好了,接下来就是Server代码
- package com.xing.studyTest.net.im.server;
-
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Set;
- import java.util.concurrent.Executor;
- import java.util.concurrent.Executors;
-
- import com.xing.studyTest.net.im.model.MessageBean;
- import com.xing.studyTest.net.im.model.SocketBean;
-
- /**
- *
- * @author xinghua
- *
- */
- public class SocketServer {
- private static ServerSocket ss;//服务端服务对象
- public static HashMap<String, SocketBean> onlines;//存储上线的Socket信息
-
- //1.准备服务端对象及容器
- static {
- try {
- ss = new ServerSocket(8520);
- onlines = new HashMap<String, SocketBean>();//新建一个容器存放客户端连接信息
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- //2.多线程实现监听消息处理
- class CatClientThread extends Thread {
- private Socket socket;//链接
- private MessageBean messageBean;//消息
- private ObjectInputStream ois;//读取消息
- private ObjectOutputStream oos;//输出消息
-
- public CatClientThread(Socket socket) {
- this.socket = socket;
- }
-
- @Override
- public void run() {
- try {
- messageBean = (MessageBean)new ObjectInputStream(socket.getInputStream()).readObject();
- System.out.println("获取消息对象:"+messageBean);
- //根据请求类型进行不同的操作
- switch (messageBean.getType()) {
- case 0: { // 上线
- System.out.println("上线1.记录上线客户的用户名和端口,组装用户名和Socket连接,添加到容器中");
- SocketBean socketBean = new SocketBean();
- socketBean.setName(messageBean.getName());
- socketBean.setSocket(socket);
- onlines.put(messageBean.getName(), socketBean);//添加到onlines中
- System.out.println("上线2.已存储上线,开始准备发送消息给客户端");
- System.out.println("当前在线人数:【"+onlines.keySet().size()+"】个");
- MessageBean returnMessageBean = new MessageBean();
- returnMessageBean.setType(0);
- returnMessageBean.setInfo(messageBean.getTimer() + " [ " + messageBean.getName() + " ]上线了");
- System.out.println("上线3.发送消息准备完毕,发送给全部用户:");
- System.out.println(onlines.keySet());
- // System.out.println(onlines.values());
- HashSet<String> set = new HashSet<String>();
- set.addAll(onlines.keySet());
- returnMessageBean.setClients(set);
- sendAll(returnMessageBean);
- System.out.println("上线4.发送有人上线消息给全部用户完毕");
- break;
- }
- case -1: { // 下线
- // try {
- // oos = new ObjectOutputStream(socket.getOutputStream());
- // oos.writeObject(messageBean);
- // oos.flush();
- // } catch (IOException e) {
- // e.printStackTrace();
- // }
- System.out.println("下线1.将用户从容器删除");
- onlines.remove(messageBean.getName());
- System.out.println("下线2.用户已移除,准备发送消息告诉所有人他下线了");
- MessageBean returnMessageBean = new MessageBean();
- returnMessageBean.setType(-1);
- returnMessageBean.setInfo(messageBean.getTimer() + " [ " + messageBean.getName() + " ]下线了");
- System.out.println("下线3.发送消息准备完毕,发送给全部用户");
- sendAll(returnMessageBean);
- System.out.println("下线4.发送有人下线消息给全部用户完毕");
- break;
- }
- case 1: { // 聊天
- System.out.println("聊天1.组装消息,准备给选中的用户发送");
- MessageBean returnMessageBean = new MessageBean();
- returnMessageBean.setType(1);
- returnMessageBean.setClients(messageBean.getClients());
- returnMessageBean.setName(messageBean.getName());//选中的用户昵称
- returnMessageBean.setInfo(messageBean.getInfo());//消息内容
- returnMessageBean.setTimer(messageBean.getTimer());//发送时间
- System.out.println("聊天2.组装消息准备完毕开始发送");
- System.out.println(returnMessageBean);
- sendMessage(returnMessageBean);
- System.out.println("聊天3.发送消息完毕");
- break;
- }
- case 2: { // 请求接受文件
- break;
- }
- case 3: { // 确定接收文件
- break;
- }
- default: {
- break;
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- close();
- }
- }
- // 向选中的用户发送数据
- private void sendMessage(MessageBean messageBean) {
- // 首先取得所有的values
- Set<String> cbs = onlines.keySet();
- Iterator<String> it = cbs.iterator();
- // 选中客户
- HashSet<String> clients = messageBean.getClients();
- while (it.hasNext()) {
- // 在线客户
- String client = it.next();
- // 选中的客户中若是在线的,就发送
- if (clients.contains(client)) {
- Socket c = onlines.get(client).getSocket();
- ObjectOutputStream oos;
- try {
- oos = new ObjectOutputStream(c.getOutputStream());
- oos.writeObject(messageBean);
- oos.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- /*
- * 向所有的用户发送数据
- */
- public void sendAll(MessageBean serverBean) {
- Collection<SocketBean> clients = onlines.values();
- Iterator<SocketBean> it = clients.iterator();
- ObjectOutputStream oos;
- while (it.hasNext()) {
- Socket c = it.next().getSocket();
- try {
- oos = new ObjectOutputStream(c.getOutputStream());
- oos.writeObject(serverBean);
- oos.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /*
- * 关闭Socket连接
- */
- private void close() {
- if (oos != null) {
- try {
- oos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (ois != null) {
- try {
- ois.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
- /*
- * 循环调用监听与本Socket的连接信息,
- */
- public void start() {
- try {
- Executor executor = Executors.newFixedThreadPool(3);
-
- while (true) {
- String name = ss.getInetAddress().getHostName();
- System.out.println("启动服务器监听程序启动完成,快来给我发送消息把!:host:"+name+"port:"+ss.getLocalPort());
- Socket socket = ss.accept();
- name = socket.getInetAddress().getHostName();
- System.out.println("收到host:"+name+"port:"+socket.getPort()+"的消息处理开始");
- Long timeStart = System.currentTimeMillis();
- executor.execute(new CatClientThread(socket));
- // new CatClientThread(socket).start();
- System.out.println("收到host:"+name+"port:"+socket.getPort()+"的消息处理完毕,用时【"+(System.currentTimeMillis()-timeStart)+"】秒");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
四、最后启动:
- package com.xing.studyTest.net.im.main;
-
- import com.xing.studyTest.net.im.server.SocketServer;
-
- /**
- * 启动服务端
- * @author xinghua
- *
- */
- public class ServerApplication {
-
- public static void main(String[] args) {
- new SocketServer().start();
- }
-
- }
五、此时就在监听 等待客户端发消息来连接了
六、简单的客户端搞个上线信息发送:
- package com.xing.studyTest.net.im.main;
-
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.net.Socket;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Scanner;
-
- import com.xing.studyTest.net.im.model.MessageBean;
-
- /**
- * 客户端
- * @author xinghua
- *
- */
- public class ClientApplication2 {
- private static final String HOST = "localhost";//host
- private static final int PORT = 8520;//端口
- private static final String NAME = "雅楠";//host
-
- public static void main(String[] args) {
- Socket socket = null;
- DataInputStream dataInputStream = null;
- DataOutputStream dataOutputStream = null;
-
- try {
- Scanner input = new Scanner(System.in);
- System.out.println("请输入一个昵称");
- String name = input.nextLine();
- System.out.println("你的昵称是【"+name+"】,开始连接。。。");
- //上线
- MessageBean messageBean = new MessageBean();
- messageBean.setType(0);
- messageBean.setName(name);
- messageBean.setTimer(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
- socket = new Socket(HOST, PORT);
- // System.out.println("发起请求到->"+HOST+":"+PORT);
- ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
- oos.writeObject(messageBean);
- oos.flush();
-
- System.out.println("获取响应数据");
- MessageBean resMB = (MessageBean)new ObjectInputStream(socket.getInputStream()).readObject();
- System.out.println(resMB);
- System.out.println();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if(dataInputStream != null){
- dataInputStream.close();
- }
- if(dataOutputStream != null){
- dataOutputStream.close();
- }
- if(socket != null){
- socket.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
这是搞了个上线消息发送,并收到响应,客户端应该是不停的监听服务端发送消息,以实现聊天,还没写出来,下次再贴出来吧
好吧,自己发给自己了,啊哈哈哈哈
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。