最近学习了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();
}
}
}
}
这是搞了个上线消息发送,并收到响应,客户端应该是不停的监听服务端发送消息,以实现聊天,还没写出来,下次再贴出来吧
好吧,自己发给自己了,啊哈哈哈哈