前段时间做一个android 客户端,需要使用公司的自由协议,完成一些通讯功能,在开发功能中,碰到了需要更改协议的一些字段结构,因此,想到是否可以将发送消息,响应消息的过程进行分离,使得在协议变化的情况下只需要更改很少的代码或者干脆继承一个类,就可以重新使用。于是,便有了下面的代码结果,不知道结构合不合理,欢迎拍砖。
1,java实现:
package com.xxx.clientservice;
import com.xxx.clientservice.MsgContent.MsgContentInf;
/**
* @Description: TODO
*/
final public class MsgUtils {
//...
final public static byte[] msgBuilder(final byte type, final MsgContentInf msgContentImp, final Object... objects)
throws Exception {
//...
// msg content ? bytes
byte[] msgBytes = msgContentImp.buildMsgContent(type, objects);
//...
return messages;
}
final static public boolean msgParse(final MsgContentInf msgContentImp, byte[] messages) {
//...
return msgContentImp.parseMsgContent((byte)(type&0x7f), arrayMsg);
}
}
package com.xxx.clientservice;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.os.Handler;
import android.os.Message;
import com.avit.clientservice.MsgContent.MsgContentInf;
final public class SendMsg {
//...
public final static void sendSysDataEvent(final onSendListener listener, final byte type,
final MsgContentInf msgContentImp, final Object... objects) {
new InnerHelpCls(listener) {
@Override
public void sendExcute() {
sendSysRemoteEvent(type, msgContentImp, objects);
}
}.start();
}
public final static void sendAppDataEvent(final onSendListener listener, final byte type,
final MsgContentInf msgContentImp, final Object... objects) {
new InnerHelpCls(listener) {
@Override
public void sendExcute() {
sendAppRemoteEvent(type, msgContentImp, objects);
}
}.start();
}
private static void sendSysRemoteEvent(final byte type, final MsgContentInf msgContentImp, final Object... objects) {
sendRemoteEvent(ClientService.SYS_REMOTE_PORT, type, msgContentImp, objects);
}
private static void sendAppRemoteEvent(final byte type, final MsgContentInf msgContentImp, final Object... objects) {
sendRemoteEvent(ClientService.APP_REMOTE_PORT, type, msgContentImp, objects);
}
private static void sendRemoteEvent(int remotePort, final byte type, final MsgContentInf msgContentImp,
final Object... objects) {
DatagramSocket localDatagramSocket = null;
try {
// build msg
byte[] arraySend = MsgUtils.msgBuilder(type, msgContentImp, objects);
// send msg
//...
//
MsgUtils.msgParse(msgContentImp, arrayReceive);
} catch (Exception localException) {
localException.printStackTrace();
} finally {
if (localDatagramSocket != null && localDatagramSocket.isConnected()) {
localDatagramSocket.close();
}
}
}
private static abstract class InnerHelpCls {
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (listener != null) {
listener.onCompletedSend();
}
}
};
private Thread thread = new Thread(new Runnable() {
@Override
public void run() {
sendExcute();
handler.sendEmptyMessage(0x111);
}
});
private onSendListener listener;
public InnerHelpCls(onSendListener listener) {
super();
this.listener = listener;
}
public void start() {
if (listener != null) {
listener.onPreparedSend();
}
thread.start();
}
public abstract void sendExcute();
}
public static interface onSendListener {
public void onPreparedSend();
public void onCompletedSend();
}
}
package com.xxx.clientservice;
final public class MsgContent {
//...
public static interface MsgContentInf {
public byte[] buildMsgContent(byte type, Object... objects);
public boolean parseMsgContent(byte type, byte[] msgContent);
}
}
2,C语言实现
#ifndef __MSG_CONTENT_H__
#define __MSG_CONTENT_H__
typedef unsigned char byte;
// msg content inf
typedef byte * build_msg_content(const byte type, const void * const msg);
typedef int parse_msg_content(const byte type, const byte * const msg);
typedef struct _tag_msg_content{
build_msg_content * build;
parse_msg_content * parse;
}msg_content_inf;
#define MSG_CONTENT_IMP msg_content_inf * msg_content_imp
#define GET_MSG_CONTENT_IMP(_POINT) (_POINT->msg_content_imp)
// msg send inf
typedef void send_prepared(void);
typedef void send_completed(void);
typedef struct _tag_msg_send{
send_prepared * prepared;
send_completed * completed;
}msg_send_inf;
#define MSG_SEND_IMP msg_send_inf * msg_send_imp
#define GET_MSG_SEND_IMP(_POINT) (_POINT->msg_send_imp)
#endif /* __MSG_CONTENT_H__*/
#ifndef __MSG_DEAL_H__
#define __MSG_DEAL_H__
#include "msg_content.h"
byte * msg_build(const byte type, const msg_content_inf * const build_imp, const void * const data);
int msg_parse(const msg_content_inf * const build_imp, const byte * const data);
#endif /* __MSG_DEAL_H__*/
#include "msg_content.h"
#include <stdio.h>
byte * msg_build(
const byte type,
const msg_content_inf * const build_imp,
const void * const data)
{
byte * msg_ret = NULL;
byte * msg = NULL;
printf("call msg_build byte = %#x, build_imp = %#x, data = %#x \n", type, build_imp, data);
// TO DO ... here
msg = build_imp->build(type, data);
// copy msg to msg_ret
// TO DO ... here
return msg_ret;
}
int msg_parse(
const msg_content_inf * const build_imp,
const byte * const data)
{
byte type = 0x01;// type should get from data
int ret = 0;
printf("call msg_parse build_imp = %#x, data = %s \n", build_imp, data);
// TO DO ... here
ret = build_imp->parse(type, data);
// TO DO ... here
return 0;
}
#ifndef __MSG_SEND_H__
#define __MSG_SEND_H__
#include "msg_content.h"
void send(
const byte type,
const void * const data,
const msg_content_inf * const msg_content_imp,
const msg_send_inf * const msg_send_imp);
#endif /* __MSG_SEND_H__*/
#include "msg_deal.h"
#include "demo.h"
#include <stdio.h>
static void send_data(
const byte type,
const void * const data,
const msg_content_inf * const msg_content_imp)
{
byte * msg = NULL;
int ret = 0;
printf("call send_data byte = %#x, msg_content_imp = %#x, data = %#x \n", type, msg_content_imp, data);
// TO DO....
msg = msg_build(type, msg_content_imp, data);
// TO DO...
//.....
ret = msg_parse(msg_content_imp, (byte *)"hello world!!!");
}
void send(
const byte type,
const void * const data,
const msg_content_inf * const msg_content_imp,
const msg_send_inf * const msg_send_imp)
{
printf("call send byte = %#x, msg_content_imp = %#x,msg_send_imp %#x, data = %#x \n", type, msg_content_imp, msg_send_imp, data);
msg_send_imp->prepared();
///{ here, you can use another thread.
send_data(type, data, msg_content_imp);
msg_send_imp->completed();
///}
}
#ifndef __DEMO_H__
#define __DEMO_H__
#include "msg_content.h"
typedef struct _tag_demo_imp{
MSG_CONTENT_IMP;
MSG_SEND_IMP;
}demo_imp;
demo_imp * get_demo_imp(void);
void destory_demo_imp(void);
#endif /* __DEMO_H__*/
#include "demo.h"
#include <stdlib.h>;
#include <stdio.h>
#include <string.h>
#include <assert.h>
static demo_imp * g_imp;
// msg content imp
static byte * demo_build_msg_content(const byte type, const void * const msg)
{
printf("call demo_build_msg_content type = %#x, msg = %#x \n", type, msg);
}
static int demo_parse_msg_content(const byte type, const byte * const msg)
{
printf("call demo_parse_msg_content type = %#x, msg = %s \n", type, msg);
}
// msg send imp
static void demo_send_prepared(void)
{
printf("call demo_send_prepared \n");
}
static void demo_send_completed(void)
{
printf("call demo_send_completed \n");
}
static void demo_imp_init(void)
{
printf("call demo_test_init \n");
g_imp = (demo_imp *)malloc(sizeof(demo_imp));
assert(g_imp != NULL);
memset((void*)g_imp, 0x00, sizeof(demo_imp));
// msg content imp
GET_MSG_CONTENT_IMP(g_imp) = (msg_content_inf *)malloc(sizeof(msg_content_inf));
assert(GET_MSG_CONTENT_IMP(g_imp) != NULL);
memset((void*)GET_MSG_CONTENT_IMP(g_imp), 0x00, sizeof(msg_content_inf));
GET_MSG_CONTENT_IMP(g_imp)->build = demo_build_msg_content;
GET_MSG_CONTENT_IMP(g_imp)->parse = demo_parse_msg_content;
// msg send imp
GET_MSG_SEND_IMP(g_imp) = (msg_send_inf *)malloc(sizeof(msg_send_inf));
assert(GET_MSG_CONTENT_IMP(g_imp) != NULL);
memset((void*)GET_MSG_SEND_IMP(g_imp), 0x00, sizeof(msg_send_inf));
GET_MSG_SEND_IMP(g_imp)->prepared = demo_send_prepared;
GET_MSG_SEND_IMP(g_imp)->completed = demo_send_completed;
}
demo_imp * get_demo_imp(void)
{
if(g_imp == NULL)
{
demo_imp_init();
}
printf("call get_demo_imp \n");
return g_imp;
}
void destory_demo_imp(void)
{
printf("call destory_demo_imp \n");
free(GET_MSG_SEND_IMP(g_imp));
GET_MSG_SEND_IMP(g_imp) = NULL;
free(GET_MSG_CONTENT_IMP(g_imp));
GET_MSG_CONTENT_IMP(g_imp) = NULL;
free(g_imp);
g_imp = NULL;
}
#include <iostream>
extern "C"{
#include "msg_send.h"
#include "demo.h"
}
int main(int argc, char ** argv){
demo_imp * imp = get_demo_imp();
send(0x00, "hello world", GET_MSG_CONTENT_IMP(imp), GET_MSG_SEND_IMP(imp));
destory_demo_imp();
return 0;
}
C运行结果:
call demo_test_init
call get_demo_imp
call send byte = 0, msg_content_imp = 0x4114c0,msg_send_imp 0x4114f8, data = 0x12c5a48
call demo_send_prepared
call send_data byte = 0, msg_content_imp = 0x4114c0, data = 0x12c5a48
call msg_build byte = 0, build_imp = 0x4114c0, data = 0x12c5a48
call demo_build_msg_content type = 0, msg = 0x12c5a48
call msg_parse build_imp = 0x4114c0, data = hello world!!!
call demo_parse_msg_content type = 0x1, msg = hello world!!!
call demo_send_completed
call destory_demo_imp