-----------------------------------------------------------------------------------
------------------ 四、公共部分:(test.qq.common) --------------
-----------------------------------------------------------------------------------
4.1 封装消息类Message:
---------------------------------------------------------------------------------------
public abstract class Message <T> {
//客户端发送给服务器:刷新好友列表
public static final int CLIENT_TO_SERVER_REFERSH_FRIENDS = 1;
//客户端发送给服务器:文本消息--群聊
public static final int CLIENT_TO_SERVER_CHATS = 2;
//客户端发送给服务器:文本消息--私聊
public static final int CLIENT_TO_SERVER_CHAT_SINGLE = 3;
//服务器发送给客户端:好友列表
public static final int SERVER_TO_CLIENT_FRIENDLIST = 4;
//服务器发送给客户端:聊天消息--群聊
public static final int SERVER_TO_CLIENT_CHAT_MESSAGE = 5;
public static final int SERVER_TO_CLIENT_CHAT_MESSAGE_SINGLE = 6;
//
//消息内容
private T messageContent;
//获取消息内容
public T getMessageContent() {
return messageContent;
}
//设置消息内容
public void setMessageContent(T messageContent) {
this.messageContent = messageContent;
}
}
4.2 消息工厂类Factory:
---------------------------------------------------------------------------------------
/**
* 消息工厂
*/
public class MessageFactory {
/**
* 组装客户端发送的文本消息--群聊
*/
public static byte[] popClientTextMessage(String msg)
{
return popMsg(Message.CLIENT_TO_SERVER_CHATS,msg.getBytes());
}
/**
* 组装客户端发送的文本消息--私聊
*/
public static byte[] popClientTextMessageSingle(String msg,String destClientInfo)
{
//消息类型
byte [] clientChatMsg = msg.getBytes();
//
byte[] userInfoArr = destClientInfo.getBytes();
//总消息长度
byte[] allArr = new byte[4 + 4 + userInfoArr.length + 4 + clientChatMsg.length];
//消息类型
System.arraycopy(Util.int2Bytes(Message.CLIENT_TO_SERVER_CHAT_SINGLE), 0, allArr, 0, 4);
//用户信息长度
System.arraycopy(Util.int2Bytes(userInfoArr.length), 0, allArr, 4, 4);
//用户信息内容
System.arraycopy(userInfoArr,0,allArr,8,userInfoArr.length);
//聊天内容长度
System.arraycopy(Util.int2Bytes(clientChatMsg.length) , 0 , allArr , (4 + 4 + userInfoArr.length) , 4);
//聊天内容
System.arraycopy(clientChatMsg , 0 , allArr , 4 + 4 + userInfoArr.length + 4 , clientChatMsg.length);
return allArr ;
}
/**
* 组装客户端刷新好友列表消息
*/
public static byte[] popClientRefleshFriends()
{
return Util.int2Bytes(Message.CLIENT_TO_SERVER_REFERSH_FRIENDS);
}
/**
* 组装好友列表
*/
public static byte [] popServerFriends(ArrayList<String> msg)
{
//将消息内容对象通过序列化转换成字节数组
byte [] msgArr = Util.serialize(msg);
return popMsg(Message.SERVER_TO_CLIENT_FRIENDLIST,msgArr);
}
/**
* 组装服务器发送消息 ---群聊
* --------------------------------------------
* | | | | 4个字节---->消息类型
* --------------------------------------------
* | | | | 4个字节---->客户端信息长度
* --------------------------------------------
* | | | | n个字节---->客户端信息
* --------------------------------------------
* | | | | 4个字节---->消息长度
* --------------------------------------------
* | | | | n个字节---->消息内容
* --------------------------------------------
*/
public static byte[] popServerChatMessage(String userInfo,byte[] clientChatMsg){
//用户信息数组
byte[] userInfoArr = userInfo.getBytes();
//总消息长度
byte[] allArr = new byte[4 + 4 + userInfoArr.length + 4 + clientChatMsg.length];
//消息类型
System.arraycopy(Util.int2Bytes(Message.SERVER_TO_CLIENT_CHAT_MESSAGE), 0, allArr, 0, 4);
//用户信息长度
System.arraycopy(Util.int2Bytes(userInfoArr.length), 0, allArr, 4, 4);
//用户信息内容
System.arraycopy(userInfoArr,0,allArr,8,userInfoArr.length);
//聊天内容长度
System.arraycopy(Util.int2Bytes(clientChatMsg.length) , 0 , allArr , (4 + 4 + userInfoArr.length) , 4);
//聊天内容
System.arraycopy(clientChatMsg , 0 , allArr , 4 + 4 + userInfoArr.length + 4 , clientChatMsg.length);
return allArr ;
}
/**
* 组装服务器发送消息 ---私聊
* @param userInfo
* @param clientChatMsg
* @return
*/
public static byte[] popServerChatMessageSingle(String senderInfo,byte[] clientChatMsg){
//用户信息数组
byte[] userInfoArr = senderInfo.getBytes();
//总消息长度
byte[] allArr = new byte[4 + 4 + userInfoArr.length + 4 + clientChatMsg.length];
//消息类型
System.arraycopy(Util.int2Bytes(Message.SERVER_TO_CLIENT_CHAT_MESSAGE_SINGLE), 0, allArr, 0, 4);
//用户信息长度
System.arraycopy(Util.int2Bytes(userInfoArr.length), 0, allArr, 4, 4);
//用户信息内容
System.arraycopy(userInfoArr,0,allArr,8,userInfoArr.length);
//聊天内容长度
System.arraycopy(Util.int2Bytes(clientChatMsg.length) , 0 , allArr , (4 + 4 + userInfoArr.length) , 4);
//聊天内容
System.arraycopy(clientChatMsg , 0 , allArr , 4 + 4 + userInfoArr.length + 4 , clientChatMsg.length);
return allArr ;
}
/**
* 组装消息数组
*/
private static byte [] popMsg(int type, byte [] msgArr)
{
//消息内容长度数组
byte [] msgLenArr = Util.int2Bytes(msgArr.length);
//消息类型
byte [] typeArr = Util.int2Bytes(type);
byte [] all = new byte[msgArr.length + msgLenArr.length + typeArr.length];
System.arraycopy(typeArr, 0, all, 0, typeArr.length);
System.arraycopy(msgLenArr, 0, all, typeArr.length, msgLenArr.length);
System.arraycopy(msgArr, 0, all, typeArr.length + msgLenArr.length, msgArr.length);
return all;
}
/**
* 解析消息流
*/
public static Message parseMessageFromInputStream(InputStream is)
{
try {
//报头4字节都是消息类型
byte [] typeArr = new byte [4];
//
is.read(typeArr);
//获取消息类型
int type = Util.bytes2Int(typeArr);
switch (type) {
//客户端请求刷新好友列表消息
case Message.CLIENT_TO_SERVER_REFERSH_FRIENDS:
return new ClientReflashFriendsListMessage();
//客户端发送消息给服务器---群聊
case Message.CLIENT_TO_SERVER_CHATS:
byte [] lenArr = new byte [4];
is.read(lenArr);
int len = Util.bytes2Int(lenArr);
byte [] strArr = new byte [len];
is.read(strArr);
return new ClientSendChatMessage(strArr);
//客户端发送消息给服务器---私聊
case Message.CLIENT_TO_SERVER_CHAT_SINGLE:
//解析目的地客户端信息
byte [] desClientInfolenArr = new byte [4];
is.read(desClientInfolenArr);
int desClientInfolen = Util.bytes2Int(desClientInfolenArr);
byte [] desClientInfoArr = new byte [desClientInfolen];
is.read(desClientInfoArr);
//destClient info
String desClientInfoStr = new String(desClientInfoArr);
//解析发送的消息
byte [] desClientMsglenArr = new byte [4];
is.read(desClientMsglenArr);
int desClientMsglen = Util.bytes2Int(desClientMsglenArr);
byte [] desClientMsgArr = new byte [desClientMsglen];
is.read(desClientMsgArr);
//组装消息
return new ClientSendChatMessageSingle(new ChatSingleBean(desClientInfoStr, desClientMsgArr));
//服务器转发客户端消息---群聊
case Message.SERVER_TO_CLIENT_CHAT_MESSAGE:
//客户端信息长度
byte [] clientInfolenArr = new byte [4];
is.read(clientInfolenArr);
int clientInfolen = Util.bytes2Int(clientInfolenArr);
byte [] clientInfoArr = new byte [clientInfolen];
is.read(clientInfoArr);
String clientInfoStr = new String(clientInfoArr);
//客户端信息
byte [] clientMsglenArr = new byte [4];
is.read(clientMsglenArr);
int clientMsglen = Util.bytes2Int(clientMsglenArr);
byte [] clientMsgArr = new byte [clientMsglen];
is.read(clientMsgArr);
String clientMsgStr = new String(clientMsgArr);
return new ServerChatMessage(new String[]{clientInfoStr,clientMsgStr});
//服务器转发客户端消息 ---私聊
case Message.SERVER_TO_CLIENT_CHAT_MESSAGE_SINGLE:
//解析发送方信息
byte [] sendclientInfolenArr = new byte [4];
is.read(sendclientInfolenArr);
int sendclientInfolen = Util.bytes2Int(sendclientInfolenArr);
byte [] sendclientInfoArr = new byte [sendclientInfolen];
is.read(sendclientInfoArr);
String sendclientInfoStr = new String(sendclientInfoArr);
//纯消息字节数组
byte [] sendclientMsglenArr = new byte [4];
is.read(sendclientMsglenArr);
int sendclientMsglen = Util.bytes2Int(sendclientMsglenArr);
byte [] sendclientMsgArr = new byte [sendclientMsglen];
is.read(sendclientMsgArr);
return new ServerChatMessageSingle(new ChatSingleBean(sendclientInfoStr, sendclientMsgArr));
//服务器发送好友列表给客户端
case Message.SERVER_TO_CLIENT_FRIENDLIST:
//客户端信息长度
byte [] friendListlenArr = new byte [4];
is.read(friendListlenArr);
int friendListlen = Util.bytes2Int(friendListlenArr);
byte [] friendListArr = new byte [friendListlen];
is.read(friendListArr);
List<String> list = (List<String>)Util.deSerialize(friendListArr);
return new ServerFriendsListMessage(list);
}
} catch (Exception e) {
}
return null;
}
}
4.3 Message类的子类:服务器端具体消息类
---------------------------------------------------------------------------------------
- 4.3.1 : 服务器端消息类NO1.------发送给客户端的消息--群聊
public class ServerChatMessage extends Message<String []>
{
public ServerChatMessage(String [] info) {
this.setMessageContent(info);
}
}
- 4.3.2: 服务器端消息类NO2.------发送给客户端的消息--私聊
public class ServerChatMessageSingle extends Message<ChatSingleBean>
{
public ServerChatMessageSingle(ChatSingleBean info) {
this.setMessageContent(info);
}
}
- 4.3.3: 服务器端消息类NO3.------发送好友列表给客户端
public class ServerFriendsListMessage extends Message<List<String>>
{
public ServerFriendsListMessage(List<String> list)
{
super.setMessageContent(list);
}
}
4.4 Message类的子类:客户端具体消息类
---------------------------------------------------------------------------------------
- 4.4.1 : 客户端消息类NO1.------向服务器发送消息-----群聊
public class ClientSendChatMessage extends Message<byte []>
{
public ClientSendChatMessage(byte[] messageContent) {
this.setMessageContent(messageContent);
}
}
- 4.4.2: 客户端消息类NO2.------向服务器发送消息------私聊
public class ClientSendChatMessageSingle extends Message<ChatSingleBean>
{
public ClientSendChatMessageSingle(ChatSingleBean messageContent) {
this.setMessageContent(messageContent);
}
}
- 4.4.3: 客户端消息类NO3.------向服务器请求刷新好友列表
public class ClientReflashFriendsListMessage extends Message
{
}
4.5 私聊消息封装类---仅用于私聊:
---------------------------------------------------------------------------------------
public class ChatSingleBean {
private String cilentInfo;
//聊天信息(纯内容)
private byte[] chat;
public String getReceiver() {
return cilentInfo;
}
public void setReceiver(String cilentInfo) {
this.cilentInfo = cilentInfo;
}
public byte[] getChat() {
return chat;
}
public void setChat(byte[] chat) {
this.chat = chat;
}
public ChatSingleBean(String cilentInfo, byte[] chat) {
this.cilentInfo = cilentInfo;
this.chat = chat;
}
}
-----------------------------------------------------------------------------------
------------------ 五、工具类部分:(test.qq.util) ------------
-----------------------------------------------------------------------------------
/**
* 工具类
*/
public class Util {
/**
* 将int转换成字节数组
*/
public static byte[] int2Bytes(int i)
{
byte[] bs = new byte[4];
bs[0] = (byte)(i >>> 24);
bs[1] = (byte)(i >>> 16);
bs[2] = (byte)(i >>> 8);
bs[3] = (byte)(i >>> 0);
return bs;
}
/**
* 将字节数组前4位,转换成int
*/
public static int bytes2Int(byte [] bs)
{
int i0 = (bs[0] & 0xff) <<24;
int i1 = (bs[1] & 0xff) <<16;
int i2 = (bs[2] & 0xff) <<8;
int i3 = (bs[3] & 0xff) <<0;
return i0 | i1 | i2 | i3;
}
/**
* 将字节数组off位 + 4位, 转换成int
*/
public static int bytes2Int(byte [] bs , int offset)
{
int i0 = (bs[0 + offset] & 0xff) <<24;
int i1 = (bs[1 + offset] & 0xff) <<16;
int i2 = (bs[2 + offset] & 0xff) <<8;
int i3 = (bs[3 + offset] & 0xff) <<0;
return i0 | i1 | i2 | i3;
}
/**
* 序列化内存对象到字节数组
*/
public static byte[] serialize(Serializable src)
{
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(src);
oos.close();
baos.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 反序列化对象字节到内存对象
*/
public static Object deSerialize(byte [] bArr)
{
try {
ByteArrayInputStream bais = new ByteArrayInputStream(bArr);
ObjectInputStream ois = new ObjectInputStream(bais);
Serializable copy = (Serializable)ois.readObject();
ois.close();
bais.close();
return copy;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 提取客户端信息
*/
public static String getClientInfo(Socket s) {
InetSocketAddress is = (InetSocketAddress)s.getRemoteSocketAddress();
//远程ip地址
String ip = is.getAddress().getHostAddress();
int port = is.getPort();
return ip +":"+ port;
}
}