加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
README-EN 10.08 KB
一键复制 编辑 原始数据 按行查看 历史
calvinwilliams 提交于 2014-08-26 00:50 . UPDATE TO V1.0.0
FlatMessages - Fast binary message format
1.Overview
FlatMessages is a cross-platform fast binary message format, little memory used , without packing and unpacking and can be used immediately, widely used in games, high-performance application server, memory constrained embedded and mobile devices, etc. FlatMessages allows you to directly access the message buffer in all fields, sent to the client without packaging , server access directly without unpacking message buffer in all fields.
FlatMessages currently only supports C language , the future will also support C++, Java and other languages.
FlatMessages is light and easy to use, does not depend on other third-party libraries.
The command line tools 'fmc' used to generate the C structure, and related tools functions , in the future will also support C++, Java classes.
Why use FlatMessages ?
* Compact binary stream : All field of FlatMessages message distribute in flat buffer, a field close to the next field, the layout is very compact, so the memory is very small. Command line tools 'fmc' that according to message definition, automatically generate C structure, through the pointer to directly access all of the fields in the buffer.
* High performance : by automatically generated with C structure directly access the message buffer pointer, to avoid the communication message packaging and unpacking, so very fast, is the extreme pursuit of performance in the scene first message format.
* Flexible message defined syntax : command line tools 'fmc' read definition file, generate specific language of the automation code, supports sub message nested, message array, such as the definition file contains the flexible configuration mode.
* Cross-platform : FlatMessages supports WINDOWS, Linux, AIX, such as the mainstream operating system, the automation code generated by the current C, in the future will also support mainstream language C++, Java, etc.
message buffer ...| 4 bytes | 8 bytes |64+1bytes|...
A A A
H H H
C Structure variable...|int*seqno|double*amount|char*name|...
2.Install with compiling
for Linux
$ tar xvzf fmc-1.0.0.tar.gz
$ cd fmc-1.0.0
$ su
# make -f makefile.Linux install
make[1]: Entering directory `/home/calvin/exsrc/fmc-1.0.0/src'
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c util.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c main.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c ReadFmcFile.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c GenerateCCode.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o fmc util.o main.o fmc.o ReadFmcFile.o GenerateCCode.o -L.
cp -f fmc /usr/bin/
make[1]: Leaving directory `/home/calvin/exsrc/fmc-1.0.0/src'
make[1]: Entering directory `/home/calvin/exsrc/fmc-1.0.0/test'
make[2]: Entering directory `/home/calvin/exsrc/fmc-1.0.0/test/test1'
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test test.o test.fmc.o -L.
mkdir -p /root/include
cp -f test.fmc.h /root/include/
make[2]: Leaving directory `/home/calvin/exsrc/fmc-1.0.0/test/test1'
make[2]: Entering directory `/home/calvin/exsrc/fmc-1.0.0/test/test2'
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test test.o test.fmc.o -L.
cp -f test.fmc.h /root/include/
make[2]: Leaving directory `/home/calvin/exsrc/fmc-1.0.0/test/test2'
make[2]: Entering directory `/home/calvin/exsrc/fmc-1.0.0/test/test9'
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test test.o test.fmc.o -L.
cp -f test.fmc.h /root/include/
make[2]: Leaving directory `/home/calvin/exsrc/fmc-1.0.0/test/test9'
make[1]: Leaving directory `/home/calvin/exsrc/fmc-1.0.0/test'
3.Basic use
3.1.Write a message definition file
[code]
$ cat test.fmc
MESSAGE TestMessage
{
INT 1 version
STRING 32 name
INT 2 oper_number
INT 4 library_card_number
FLOAT 4 amount
FLOAT 8 balance
STRING 128 remark
}
[/code]
3.2.Use the tools 'fmc' processing it and generate automation code
[code]
$ fmc -f test.fmc -c
MESSAGE TestMessage
INT 1 version
STRING 32 name
INT 2 oper_number
INT 4 library_card_number
FLOAT 4 amount
FLOAT 8 balance
STRING 128 remark
ok!
$ ls
test.fmc
test.fmc.h
test.fmc.c
test.fmc.LOG.c
[/code]
3.3.Write application , compiled into executable file together, to execute
[code]
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test.fmc.h"
#include "test.fmc.LOG.c"
int test()
{
FMCCOM_TestMessage com ;
FMCREF_TestMessage ref ;
long comlen ;
/* init communication buffer */
memset( & com , 0x00 , sizeof(FMCCOM_TestMessage) );
/* client code */
memset( & ref , 0x00 , sizeof(FMCREF_TestMessage) );
FMCBIND_TestMessage( & com , FMCLEN_TestMessage , & ref );
*(ref.version) = 1 ;
strcpy( ref.name , "calvin" );
*(ref.oper_number) = 12345 ;
*(ref.library_card_number) = 1234567890 ;
*(ref.amount) = 100.00 ;
*(ref.balance) = 10000.00 ;
strcpy( ref.remark , "my remark" );
comlen = FMCLEN_TestMessage ;
FMCUNBIND_TestMessage( & ref , & com , & comlen );
/* ... client send communication buffer to server in '& com' with length 'comlen' ... */
/* server code */
memset( & ref , 0x00 , sizeof(FMCREF_TestMessage) );
FMCBIND_TestMessage( & com , comlen , & ref );
FMCLOG_TestMessage( & ref );
return 0;
}
int main()
{
return -test();
}
$ make
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test test.o test.fmc.o -L.
$ ./test
TestMessage.version[1]
TestMessage.name[calvin]
TestMessage.oper_number[12345]
TestMessage.library_card_number[1234567890]
TestMessage.amount[100.000000]
TestMessage.balance[10000.000000]
TestMessage.remark[my remark]
[/code]
4.FlatMessages Message definition syntax
Below is an example of a comprehensive
[code]
$ cat test.fmc
MESSAGE BankTransaction
{
INT 1 version DEFAULT 1
INCLUDE head.fmc
MESSAGE QueryTransactionDetails
{
MESSAGE AddonMessages ARRAY 3
{
STRING 64 message_text
}
MESSAGE TransactionDetailTitle
{
STRING 64 title_text DEFAULT "MY TITLE"
INT 2 page_no DEFAULT 1
INT 2 page_size
}
MESSAGE TransactionDetails ARRAY 10
{
STRING 10 trans_date
STRING 10 trans_time
STRING 6 outlet_id DEFAULT "1001"
STRING 20 card_no
FLOAT 4 trans_amount
}
}
}
$ cat head.fmc
MESSAGE ResponseHeader
{
STRING 32 transaction_code
INT 4 trans_jnlsno
INT 4 response_code DEFAULT 0
STRING 1024 response_desc DEFAULT "OK"
}
[/code]
By keyword 'DEFAULT' at the back of the field is the DEFAULT value, the function of automatic generation FMCINIT_BankTransaction batch initialization.
The field type and length currently supporte :
INT 1,2,4
FLOAT 4,8
STRING N
5.Performance pressure
Pressure environment :
CPU : Intel(R) Core(TM) i3-3240 CPU 3.4GHz 3.4GHz
Memory : 2GB
OS : WINDOWS XP SP3 ( VMWare 6.0.1 ( Red Hat Enterprise Linux Server release 5.4 ) )
[code]
$ cat test.fmc
MESSAGE PersonalInfoList
{
MESSAGE PersonalInfo ARRAY 37
{
INT 4 id
STRING 64 name
INT 1 age
STRING 1 gender DEFAULT "M"
INT 4 phone_num
}
}
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "test.fmc.h"
#include "test.fmc.LOG.c"
int press( long press_count )
{
FMCCOM_PersonalInfoList com ;
FMCREF_PersonalInfoList ref ;
long comlen ;
long c ;
long t1 , t2 , dt ;
time( & t1 );
memset( & com , 0x00 , sizeof(FMCCOM_PersonalInfoList) );
comlen = sizeof(FMCCOM_PersonalInfoList) ;
memset( & ref , 0x00 , sizeof(FMCREF_PersonalInfoList) );
FMCBIND_PersonalInfoList( & com , comlen , & ref );
FMCINIT_PersonalInfoList( & com , & ref );
*(ref.PersonalInfo[36].id) = 1001 ;
strcpy( ref.PersonalInfo[36].name , "Calvin" );
*(ref.PersonalInfo[36].age) = 35 ;
*(ref.PersonalInfo[36].phone_num) = 12345678 ;
for( c = 0 ; c < press_count ; c++ )
{
FMCUNBIND_PersonalInfoList( & ref , & com , & comlen );
memset( & ref , 0x00 , sizeof(FMCREF_PersonalInfoList) );
FMCBIND_PersonalInfoList( & com , comlen , & ref );
}
FUNCNAME_FMCLOG_PersonalInfoList( & ref );
time( & t2 );
dt = t2 - t1 ;
printf( "sizeof(FMCCOM_PersonalInfoList)[%d]\n" , sizeof(FMCCOM_PersonalInfoList) );
printf( "EPLASE %ld seconds\n" , dt );
return 0;
}
static void usage()
{
printf( "USAGE : test press_count\n" );
}
int main( int argc , char *argv[] )
{
if( argc != 1 + 1 )
{
usage();
exit(7);
}
return -press( atol(argv[1]) );
}
$ make
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test.fmc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test test.o test.fmc.o -L.
$ time ./test 100000000
...
PersonalInfoList.PersonalInfo[index[1]].id[1001]
PersonalInfoList.PersonalInfo[index[1]].name[Calvin]
PersonalInfoList.PersonalInfo[index[1]].age[35]
PersonalInfoList.PersonalInfo[index[1]].gender[M]
PersonalInfoList.PersonalInfo[index[1]].phone_num[12345678]
sizeof(FMCCOM_PersonalInfoList)[2812]
EPLASE 7 seconds
real 0m6.716s
user 0m6.698s
sys 0m0.013s
[/code]
6.Finally
Welcome to use, if you met with a problem or have a cool idea, please tell me, thank you ^_^
Project home page : [url]https://github.com/calvinwilliams/FlatMessages[/url]
Email : calvinwilliams.c@gmail.com
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化