<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
 <channel>
  <title> Project News</title>
  <link>http://unix-center.org/news/</link>
  <description>Unix-Center GForge Project News</description>
  <language>en-us</language>
  <copyright>Copyright 2000-2010 Unix-Center GForge OSI</copyright>
  <webMaster>admin@unix-center.org</webMaster>
  <lastBuildDate>Fri, 30 Jul 2010 4:10:02 GMT</lastBuildDate>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Unix-Center GForge RSS generator</generator>
  <image>
    <url>http://unix-center.org/images/bflogo-88.png</url>
    <title>Unix-Center GForge Developer</title>
    <link>http://unix-center.org/</link>
    <width>124</width>
    <heigth>32</heigth>
  </image>
  <item>
   <title>第一步 Bootload 完成</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=609</link>
   <description>现在已经有一个简单的bootload已完成，
用qemu来模拟x86，成功的打印出：
leios Bootload.
</description>
   <author>lei.wang@users.unix-center.org (lei.wang Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=609</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=609</comment>
  </item>
  <item>
   <title>wbedit v1.01发布了</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=569</link>
   <description>wbEdit 是我以自己名字命名的一款在线编辑器。 
虽然目前功能很单一，但我希望它会慢慢超越fck。并成为全世界最好的编辑器。 
我每天都会花时间来维护这个编辑器，并改进它。让我们做的更好。 
有兴趣的童鞋可以与我联系： 
howtodesign@sina.com 
tianjinjava@gmail.com 
916180588@qq.com 
wenbo 2010-02-08 
</description>
   <author>ppsoy@users.unix-center.org (文博 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=569</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=569</comment>
  </item>
  <item>
   <title>webIM提供下载2个版本</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=565</link>
   <description>分别是有数据库的和无数据库的</description>
   <author>ppsoy@users.unix-center.org (文博 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=565</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=565</comment>
  </item>
  <item>
   <title>Think库之NETCENTER接口（socket通讯框架）</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=543</link>
   <description>Think NETCENTER是借鉴ACE的设计思路，即使用select对所有连接进行侦听，如有连接上有事件发生，则调用相应的回调函数进行处理，这里采用缓冲的方式先将数据接收到缓冲区，然后调用相应的回调函数进行处理，当然如果接口是可写的，那么将查看写缓冲区是否有数据，如果有则从缓冲区读取数据进行发送。
1：建立网络中心
THINK_NETCENTER *think_netcenter_new();
主要是得到一个名柄，网络中心操作名柄
2：进行一次网络处理
int think_netcenter_idle(THINK_NETCENTER *netcenter,int timeout);
这个接口为网络中心的总控接口，它先去调用select进行事件侦听，然后进行数据接收并调用回调函数进行处或从缓冲区发送数据，直到所有接口处理完毕后才返回，应用层需要不断调用此接口完成网络数据的持续处理
timeout与think_netselect中的意思完全一样，这个参数就是原封不动的传给think_netselect的。
3：释放网络中心
int think_netcenter_free(THINK_NETCENTER *netcenter);
这个接口将释放所有表及内存
4：向网络中心注册连接
THINK_NETCENTER_NETLIST *think_netcenter_netadd(THINK_NETCENTER *netcenter,THINK_NET *net,THINK_NETCENTER_NETHANDLE nethandle);
net为所要注册的连接
nethandle为该连接的回调函数地址
5：从网络中心注销连接
int think_netcenter_netdel(THINK_NETCENTER *netcenter,THINK_NET *net);
6：从网络中心查找连接
THINK_NETCENTER_NETLIST *think_netcenter_netfind(THINK_NETCENTER *netcenter,THINK_NET *net);
7：清理网络中心的链表
int think_netcenter_netclean(THINK_NETCENTER *netcenter);
与think_netclean的意思一样，删除时只是置了标志，因此需要进行清理
8：从连接缓冲中读取数据
int think_netcenter_recv(THINK_NETCENTER_NET *net,void *buf,unsigned int siz);
该函数是在回调中调用的，当有数据可读时，通过这个接口可获取数据
9：向连接缓冲区中写入数据
int think_netcenter_send(THINK_NETCENTER_NET *net,const void *buf,unsigned int len);
该函数是在业务处理时调用的，当需要发送数据时，通过这个接口将数据发送到该连接的缓冲区中，由网络中心在idle时进行发送
10：从缓冲区中窃取数据
int think_netcenter_peek(THINK_NETCENTER_NET *net,void *buf,unsigned int siz);
当不知道缓冲区里有什么数据时，可用此接口进行偷窥，即将数据取出来，但缓冲区的数据仍原封不动的保留在那里，这个接口在判断缓冲区是否有完整的数据包时很有用


以下为使用ＧＬ语言通讯时使用的接口
11：判断缓冲区是否有完整的数据包
int think_netcenter_ismsgok(THINK_NETCENTER_NET *net);
完整的数据包即四字节网络字节序的长度＋对应的数据内容都在缓冲里了
12：从缓冲区接收一个数据包
int think_netcenter_recvmsg(THINK_NETCENTER_NET *net,void *buf,unsigned int siz);
13：向缓冲区发送一个数据包
int think_netcenter_sendmsg(THINK_NETCENTER_NET *net,const void *buf,unsigned int len);

以下为网络中心内部使用的接口
14：从网络上接收数据至缓冲区中
int think_netcenter_recvto(THINK_NETCENTER_NET *net);
15：从缓冲区中读取数据发送到网络上
int think_netcenter_sendfrom(THINK_NETCENTER_NET *net);
16：对网络中心的连接进行侦听
int think_netcenter_select(THINK_NETCENTER *netcenter,int timeout);
即对每个连接置相应的侦听标志，然后调用think_netselect进行侦听</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=543</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=543</comment>
  </item>
  <item>
   <title>Think库之NET接口（socket接口）</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=542</link>
   <description>Think NET是socket通讯的基本操作的封装，提供connect、listen、accept、send、recv、close几个基本接口，另外对select进行了封装，对包含socket名柄信息的双向循环链表进行侦听，同样也对ＵＮＩＸ上的poll实现了同样的封装，喜欢用poll的只需更换函数名即可，其它操作完全一样
struct __think_net {
    int sockfd;
    char ip[16];
    unsigned short port;
    int flags;
};
typedef struct __think_net THINK_NET;
1：建立连接
THINK_NET *think_netconnect(const char *ip,unsigned short port);
参数故名思意
2：建立侦听
THINK_NET *think_netlisten(const char *ip,unsigned short port);
3：THINK_NET *think_netaccept(THINK_NET *net);
net为侦听名柄
4：接收数据
int think_netrecv(THINK_NET *net,void *buf,unsigned int siz,int flags);
buf为数据存放地址
siz为大小
flags为标志，可以接受的值为THINK_NET_WAIT，即一直等到siz个字节全部接收完毕或有错误时才返回
5：发送数据
int think_netsend(THINK_NET *net,const void *buf,unsigned int len,int flags);
flags意思与think_netrecv中的相同，此处为len个字节全部发送完毕
6：关闭连接
int think_netclose(THINK_NET *net);
7：加载动态库（Windows平台必须要调用的）
int think_netstart(void);
int think_netstop(void);
netstart为使用网络接之间要调用的，netstop为不使用网络时候调用，也可以由程序退出时自动执行，即think_netstart是必须要执行的。
struct __think_netlist {
    THINK_NET *net;
    int flags;
    struct __think_netlist *prior;
    struct __think_netlist *next;
};
typedef struct __think_netlist THINK_NETLIST;
8：向链表中增加一个连接
int think_netlist_add(THINK_NETLIST **netlist,THINK_NET *net);
netlist为链表的地址，如定义一个变量THINK_NETLIST *netlist=NULL，调用时传&amp;amp;netlist即可
9：从链表删除一个连接
int think_netlist_del(THINK_NETLIST **netlist,THINK_NET *net);
10：在链表中查找一个连接
THINK_NETLIST *think_netlist_find(THINK_NETLIST *netlist,THINK_NET *net);
11：清理链表
int think_netlist_clean(THINK_NETLIST **netlist);
调用think_netlist_del时，只是将标志位置为已删除，并未真正从链中删除，因此需要调用这个接口进行清理
12：释放链表
int think_netlist_free(THINK_NETLIST **netlist);
将删除所有连接，并释放内存
13：使用select进行侦听
int think_netselect(THINK_NETLIST **netlist,int timeout);
timeout为等待时间
&amp;gt;0为阻塞式等待一定时间，直到超时
=0为非阻塞式，立即返回
&amp;lt;0为永久阻塞式，直到有事件发生
THINK_NETLIST结构中有一个成员flags，要在调用think_netselect之前，将需要侦听的事件设置好，如将flags设为THINK_NET_READ或THINK_NET_WRITE或THINK_NET_READ|THINK_NET_WRITE，即侦听读、写、读写
think_netselect返回后，通过检查该标志是否被置位成THINK_NET_READ、THINK_NET_WRITE，以得知连接目前为可读或可写
14：使用poll进行侦听
int think_netpoll(THINK_NETLIST **netlist,int timeout);
用法与think_netselect完全一样
15：发送消息
int think_netsendmsg(THINK_NET *net,const void *buf,unsigned int len);
将先送四字节网络字节序的长度，然后再发送具体长度的信息
16：int think_netrecvmsg(THINK_NET *net,void *buf,unsigned int siz);
先接收四字节网络字节序的长度，然后再接收具体长度的信息</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=542</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=542</comment>
  </item>
  <item>
   <title>Think库之GL接口（通用语言接口）</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=541</link>
   <description>Think GL为吸收了ISO8583协议及XML语言的精华而创作的通用二进制通讯语言，核心格式为字段编号，字段长度，字段内容,整个数据包都是由这三个作为一个数据项的合集
字段编号与字段长度均为四字节网络字节序（大字节序整型）
字段内容为若干长度的字符型数据
GL语言具有嵌套（思想来自XML），乱序（字段没必要按编号大小依次存放，这点由ISO8583改进而来），解析高效（二进制格式（如ISO8583）的数据包比文本格式（如XML）的数据包效率要高很多），简单（ISO8583与XML格式都很简单明了）
函数接口目前只有两个，一个是获取字段，一个是添加字段
1：获取字段
int think_gl_get(const char *msgbuf,unsigned int msglen,unsigned int no,char typ
e,unsigned int maxlen,void *data,unsigned int size);
msgbuf为数据包地址
msglen为数据包长度
no为字段编号
type为字段类型
maxlen为字段的最大允许长度
data为值的存放地址
size为值的大小
2：添加字段
int think_gl_put(char *msgbuf,unsigned int msgsiz,unsigned int no,char type,unsi
gned int maxlen,const void *data,unsigned int len);
msgbuf为数据包地址（注意是数据包剩余空间的首地址）
msgsiz为数据包大小（注意是数据包剩余空间的大小）
no为字段编号
type为字段类型
maxlen为字段的最大允许长度
data为值的存放地址
len为值的长度</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=541</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=541</comment>
  </item>
  <item>
   <title>Think工具之CONF</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=540</link>
   <description>关于CONF文件有两个小工具，getconf和showconf，其中getconf为获取配制值，showconf为显示所有配制信息
1：getconf
usage: getconf [-d delimiter] conffile h v
-d delimiter为分割符
conffile为配制文件名
h为行
v为列
2：showconf
usage: showconf [-d delimiter] conffile
-d delimiter为分割符
conffile为配制文件名</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=540</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=540</comment>
  </item>
  <item>
   <title>Think工具之CFG</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=539</link>
   <description>关于配制文件的小工具有getcfg和showcfg两个，其中getcfg是从配制文件中读取配制，并显示在屏幕上，showcfg则将配制文件中所有配制信息都显示在屏幕上
1：getcfg
usage: getcfg [-p cfgpath] [-f field] cfgfile name
-p cfgpath为配制文件搜索路径
-f field为域名
cfgfile为配制文件名
name为配制名
2：showcfg
usage: showcfg [-p cfgpath] cfgfile
-p cfgpath为配制文件搜索路径
cfgfile为配制文件名</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=539</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=539</comment>
  </item>
  <item>
   <title>Think库之CONF接口（数据文件接口）</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=538</link>
   <description>Think CONF接口可以操作/etc/passwd这样的以某字符为分割符的数据文件，如以管道符｜为分割的文件
#Name     |Type   |Length |Desc
ID       |int    |3  |ID
Name     |char   |15 |Name
Email    |char   |30 |Email
第一行为注释，因为前面有#，跟CFG文件注释规则一样，#号后面的字符全部为注释
struct __think_conf_vlist {
    char value[THINK_CONF_VALUE_SIZE];  /* column value */
    struct __think_conf_vlist *prior;
    struct __think_conf_vlist *next;
};  /* column list */
typedef struct __think_conf_vlist THINK_CONF_VLIST;

struct __think_conf_hlist {
    struct __think_conf_vlist *vlist;       /* column list */
    struct __think_conf_hlist *prior;
    struct __think_conf_hlist *next;
};  /* line list */
typedef struct __think_conf_hlist THINK_CONF_HLIST;

struct __think_conf {
    char d;                 /* column delimiter */
    unsigned int hcount;            /* line count */
    unsigned int vcount;            /* column count */
    char file[THINK_CONF_FILE_SIZE];    /* file */
    THINK_CONF_HLIST *hlist;        /* line list */
};
typedef struct __think_conf THINK_CONF;
函数接口很简单，有这么几个
1：加载数据文件
THINK_CONF *think_loadconf(const char *file,char d);
跟CFG文件处理接口类似，CONF文件也是加载到内存中的链表后再进行操作
参数d为分割符，可以为任意字符，如,;|:.等
2：获取配制值
int think_getconf(THINK_CONF *conf,int h,int v,void *value,unsigned int size,int flags);
h为行
v为列
value为值的存放地址
size为大小
flags为标志，可以取的值为：
/* field type */
#define THINK_CONF_CHAR     'C'     /* 1 bytes */
#define THINK_CONF_SHORT    'S'     /* 2 bytes */
#define THINK_CONF_INT      'I'     /* 4 bytes */
#define THINK_CONF_LONG     'L'     /* 8 bytes */
#define THINK_CONF_FLOAT    'F'     /* 4 bytes */
#define THINK_CONF_DOUBLE   'D'     /* 8 bytes */
#define THINK_CONF_MASK_TYPE    0xFF        /* field type mask */
#define THINK_CONF_NOT_EMPTY    0x0100      /* field value not empty */
3：打印所有配制信息
int think_showconf(THINK_CONF *conf);
与CFG类似，此接口将把链表中所有配制信息打印出来
4：释放内存
int think_freeconf(THINK_CONF *conf);
释放链表占用的内存</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=538</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=538</comment>
  </item>
  <item>
   <title>Think库之CFG接口（配制文件接口）</title>
   <link>http://unix-center.org/forum/forum.php?forum_id=537</link>
   <description>Think的工具中logserver的配制文件如下
[logserver]
logname=logserver
logflags=debug,print
logpath=../log
lsnaddr=*:10000
其中[logserver]为一个域（Field）
当然也可以没有域，就像这样
logname=logserver
logflags=debug,print
logpath=../log
lsnaddr=*:10000
这两种写法logserver都可以读取到配制的值
这种有域的称为局部配制，没域的称为全局配制
如果一个配制在局部配制中没有定义，则会取全局配制中该配制的值，这有点类似C++的继承的意思。
如果配制定义了，但是值为空，那么取到的值也会为空，即配制的值是允许为空的。
以上为配制文件的一些规则，下面说一下接口的用法。
struct __think_cfg_cfglist {
    char field[THINK_CFG_FIELD_SIZE];   /* field */
    char name[THINK_CFG_NAME_SIZE];     /* name */
    char value[THINK_CFG_VALUE_SIZE];   /* value */
    char file[THINK_CFG_FILE_SIZE];     /* file */
    unsigned int lineno;
    struct __think_cfg_cfglist *prior;
    struct __think_cfg_cfglist *next;
};          /* cfg list */
typedef struct __think_cfg_cfglist THINK_CFG_CFGLIST;
struct __think_cfg{
    unsigned int cfgcount;      /* cfg count */
    THINK_CFG_CFGLIST *cfglist;     /* cfg list */
};
typedef struct __think_cfg THINK_CFG;

1：加载配制文件
THINK_CFG *think_loadcfg(const char *file,const char *path);
配制文件需要先加载到内存中，即存储在一个双向循环链表里，然后只要从内存中读取配制即可，因此不需要把文件一直打开着，每次获取配制时，从头开始搜索文件
2:获取配制的值
int think_getcfg(THINK_CFG *cfg,const char *field,const char *name,void *value,unsigned int size,int flags);
field为域名，如logserver.cfg中的[logserver]
name为配制名
value为配制值的存放地址
size为配制值的大小
flags为标志，可以接受的值为
#define THINK_CFG_CHAR          'C'     /* 1 bytes */
#define THINK_CFG_SHORT         'S'     /* 2 bytes */
#define THINK_CFG_INT           'I'     /* 4 bytes */
#define THINK_CFG_LONG          'L'     /* 8 bytes */
#define THINK_CFG_FLOAT         'F'     /* 4 bytes */
#define THINK_CFG_DOUBLE        'D'     /* 8 bytes */

#define THINK_CFG_MASK_TYPE     0xFF        /* mask */

#define THINK_CFG_NOT_IGNORE        0x0100      /* not ignore */
#define THINK_CFG_NOT_EMPTY     0x0200      /* not empty */
3：打印所有配制信息
int think_showcfg(THINK_CFG *cfg);
即将链表中各项配制信息打印出来，有助于查看所有配制，因为Think的CFG接口支持配制文件的嵌套，就像C语言的#include一样，当嵌套了多层配制文件时，能够很方便的显示所有配制信息会对查看配制信息有很大帮助
4：释放配制链表
int think_freecfg(THINK_CFG *cfg);
当不再使用配制信息时，可将其占用的内存空间释放掉
另外还有的一个批量获取配制的接口，通过传递一个配制的数组，即可将数组中所有的配制都获取到
int think_getcfgs(THINK_CFG *cfg,THINK_CFGARRAY *cfgarray,unsigned int cfgcount);
数组的类型如下：
struct __think_cfgarray {
    const char *domain;
    const char *name;
    void *value;
    unsigned int size;
    int flags;
    int *exists;};      /* cfg array */
typedef struct __think_cfgarray THINK_CFGARRAY;
前面几个与单个获取配制的参数一样，最后一个exists表示配制是否存在

下面再说一下Think CFG比较高级的功能，接口还是上面那几个，这里只是介绍一下接口的高级用法
1：别名
经常有一些配制的名字起得不好，但在有些情况下又不能更配制名字，这时就可以使用别名，即给这个配制再取个名字，但是取值还是取前一个配制的值，例：
db=oracle
dbname=$db
其中dbname即为db的别名，它的取值也将为oracle
2：配制文件嵌套
即一个配制可以引用另一个或多个配制文件，另一个配制文件中也可以再引用另一个或多个配制文件，你Ｃ语言中的#include一样
例：
#include &amp;lt;global.cfg&amp;gt;
name=luojian
#address=        address定义在global.cfg中
即引用配制文件global.cfg，其中定义了配制（address）的值
3：配制搜索路径
既然支持include，那么导入的配制文件在哪找呢，Ｃ语言编译时要批定头文件搜索路径，这里也一样，因此在加载配制文件（think_loadcfg())时，需要指定参数path，path为以冒号分割的字符串，如../etc:/home/luojian/etc:/etc，这样，在加载配制文件时，会依次搜索这些目录以导入include指定的配制文件
4：覆盖
后面同名的配制可以覆盖前面的配制，即如果在global.cfg中已经定义了配制address的值，但又要改取别的值，那么有两种方法，一种是直接改global.cfg配制，一种是再定义一下address的配制
5：实时赋值
配制文件中的每行配制都依次立即生效，像shell脚本中给变量赋值一样，立即生效，因此在内存链表中，在同一个域中不会有两个同样的配制，如果配制文件中这样情况，也会在加载的时候以覆盖的规则处理掉了
6：注释
Think CFG只接受以＃开头的注释，有两个位置可以加注释，一个在一行的开头就加＃，一个是在一项配制的结尾加＃
7：宽松的格式
行首，行尾，域名前后（不包括中间），#号前后，$号前后，=号前后，配制名前后，配制值前后，这些地方的空白符（空格、TAB符）都将被忽略</description>
   <author>enigma1983@users.unix-center.org (enigma1983 Unix-Center)</author>
   <pubDate>Thu, 01 Jan 1970 0:00:00 GMT</pubDate>
   <guid>http://unix-center.org/forum/forum.php?forum_id=537</guid>
   <comment>http://unix-center.org/forum/forum.php?forum_id=537</comment>
  </item>
 </channel>
</rss>
