Aside

ngnix and fastcgi and cicstg 开发环境搭建

一个搭建HTTP Server的项目需求,虽然方案没有最终确定,使用Ngnix做代理转发,后端使用使用开发语言无关的CGI应用进行业务逻辑处理,初步技术是可行的。但使用C语言开发WebServer 应用或许真不是什么好主意,那这样想啊,我们还用CICS这么古老的东西呢?–这里又忍不住想吐槽cics了..这个架构中的毒瘤!…. 进入正题吧,首先安装ngnix,ngnix的强大就不用叨叨了,安装也相当顺利。

  • 下载安装PCRE
# wget  ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz
# ./configure;make;make install;
# wget http://nginx.org/download/nginx-1.10.2.tar.gz
# ./configure;make;make install;

这样就可以启动nginx,默认安装在了/usr/local/nginx目录下.

  • 下载安装spawn-fcgi,可以从Github Lighthtpd项目中下载,也可以直接从lighttpd.net这里下载。同样可以编译出Spawn-fcgi这个可执行程序。ngnix是支持FastCgi的,但是没有这个CGI管理程序。
  • 接下来就可以写CGI程序了,可以使用一些现成开源库,当然也可以自己写。
  • 安装CICS TRANSACTION GATEWAY,!!!NOTE!!![这玩意基本上支持32系统,安装时也会各种水土不服的,你可能需要32位的jre..]安装开发中可能需要32位支持,比如:
libXp.i686 
glibc-devel.i686

–慢慢享受其中的酸爽吧%$%$%.

  • 顺利的话应该可以写代码测试一下了。以下代码片段是接受从浏览器提交的表单然后提交CTG请求,编写代码编译。
 while (FCGI_Accept() >= 0) {   
        memset(sBufIn,0,sizeof(sBufIn));
        FCGI_fread(sBufIn, sizeof(char), sizeof(sBufIn), FCGI_stdin);
        if(strlen(sBufIn)==0)
        {
            memcpy(sBufIn,sParmas,strlen(sParmas));
        }
        memset(&tHttpIn,0x00,sizeof(HttpReqT));
        rc=InitHttpIn(&tHttpIn,sBufIn);
        resultSize= URLDecode(tHttpIn.MsgIn, tHttpIn.MsgIn, sizeof(tHttpIn.MsgIn));
        rc=CallCtgSvr(&tHttpIn);
        if(rc != RC_OK)
        {
            printf("Content-type: text/plain\r\n"
                "\r\n"
                ""
                "QUERY_STRING :%s.\n"
                "REQUEST_METHOD : %s.\n"
                "CONTENT_TYPE : %s.\n"
                "CONTENT_LENGTH : %s.\n"
                "SERVER_PROTOCOL : %s.\n"
              ...
         }
         ...
     }
     // CTG 调用函数
     // CTG_openRemoteGatewayConnection();
     // CTG_ECI_Execute(gatewayToken, &eciParms);
     // Makefile libs -m64 -lctgclient -lfcgi
  • 配置nginx 端口转发处理FASTCGI.
 location ~ \.cgi$ {
        fastcgi_pass 127.0.0.1:8000;
        fastcgi_index index.cgi;
        fastcgi_param SCRIPT_FILENAME fcgi$fastcgi_script_name;
        include fastcgi_params;
    }
  • 配置nginx 端口转发处理FASTCGI.启动CGI程序。
     /usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 8000 -f /usr/local/nginx/cgi-bin/ctgcls
  • 使用浏览器测试或其他HTTP 客户端程序测试
 #!/usr/bin/env python
#coding=utf8
import httplib, urllib
httpClient = None
try:
    #params = urllib.urlencode({'name': 'tom', 'age': 22})
    params = '''TEST CTG..'''
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    httpClient = httplib.HTTPConnection("192.168.101.181", 80, timeout=30)
    httpClient.request("POST", "/ctgcls.cgi", params, headers)
    response = httpClient.getresponse()
    print response.status
    print response.reason
    print response.read()
    print response.getheaders() #获取头信息
except Exception, e:
    print e
finally:
    if httpClient:
        httpClient.close() 
Aside

顽固的守卫-36进制转换

不得不吐槽,什么年代了,还要用哪些过时的东西。
哪些人说,稳定,人家都在用,有现成原型….
这无非是盲从,懒惰,终是无能,然而却掌握了话语权。
吐槽完毕,锅最终还是要有人背。
有个中间件软件系统,对命名,配置,参数做了严格限制。比如配置名长度必须4位,通讯队列名必须小于8位,甚至于端口号的大小也自己做了控制(65535以内还不够小?)。这个就是大名鼎鼎长度IBM帮我们省的。掌握话语权的自认为有能力驾驭好这个古董,程序猿早已对这玩意深恶痛绝:好在哪?稳定吗,高效吗?未必吧!恐怕只是不敢尝试新的,或是只是手中唯一的救命稻草?
为何还在吐槽…正题呢?呃,不好意思。
今天的槽点主要是:32GB内存为何还以为我只有64K。省确是件好事,然而要看省在哪方面。
程序中需要用到中间件队列名来匹配请求应答,而且不能重复。然后唯一可用的是流水号,是12位的。
而对列名最长8位!这点没办法了,闭源收费,你能耐我何!只有一个思路了-压缩流水:
当年数制转化是这样学的,模运算再倒序重排。效率暂不研究:

   int len=0;
    int i=0;
    char d=' ';
    int m=0;
    while(num)
    {
        m=num%36;
        if(m>9)
        {
            d='a'+m-10;
        }
        else
        {
            d='0'+m;
        }
        sprintf(des,"%s%c",des,d);
        num=num/36;
    }

        len=strlen(des);
        for(i=0;i<len/2;i++)
        {
            d=*(des+i);
            *(des+i)= *(des+len-i-1);
            *(des+len-i-1)=d;
        }

 

Aside

汉字使用默认解码出现问题

–同步自GEJOIN.COM

老生常谈的一个问题,汉字编码与解码问题,各种编码就不再复制粘贴了,需要的话维基百科捡起来再看看。

名称 第一字节 第二字节
GB2312 0xB0-0xF7(176-247) 0xA0-0xFE(160-254)
GBK 0x81-0xFE(129-254) 0x40-0xFE(64-254)

遇到一个问题,一字符串以‘|’ 分隔,解析后出现各种乱码。这显然是编码重叠导致的。 举例来看: “王文弢|赵珅|刘颖弢|田東|孙炜韡” 查看这些汉字的编码,可以看到高位中正好有|这个相同编码。

那么就需要对汉字进行必要解码而不是默认。

       unsigned char ch1 = (unsigned char) *s;
       unsigned char ch2 = (unsigned char) *(s+1);
       if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)
       {
        ...
       }

查看其代码原来使用库函数strchr,于是重新写写这个函数:

char *StrChr (char *s,char c)
{
   while(*s!='\0'&&*s!=c)
    {
       unsigned char ch1 = (unsigned char) *s;
       unsigned char ch2 = (unsigned char) *(s+1);
       if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254)
       {
            ++s;
        }
        ++s;
    }
    return *s==c ? s: NULL;
}

好了。以后再继续。

[BUG]读写文件-打开正常,无法读写

[BUG]读写文件-打开正常,无法读写

问题已经描述,请思考,其实可能很深很深……

FILE *fp;
char File_Name[]="sFile_Name";
int Func( char ** args)
{
fp=fopen(File_Name,"w");
frprintf(fp,"Writing somthing.");
SubFunc_1(args);
SubFunc_2(args);
/* do sothing */
/* ......... */
}


static int SubFunc_2(char **args)
{
if ((fp = fopen(File_Name, "rb")) == NULL)
{
return -1;
/* sorry ,It is all OK. */
}
while (fgets(sBuf, sizeof(sBuf), fp) != NULL)
{
/*opps...Null...*/
}
}

Microsoft DreamSpark已为学生提供免费的VS2013

Microsoft DreamSpark已为学生提供免费的VS2013

如果你是一个学生,通过注册DreamSpark,可以免费下载微软提供的多种软件开发工具,参加一些活动。前提还有,你需要有一个edu邮箱或其他有效的身份验证。edu邮箱呢,当然一般学校可能会为学生提供,当然也有不提供的,尤其本科生……我们学校中国矿业大学当年为本科生提供给了cumt.edu.cn的邮箱,感谢一下…

home_sparkdream

 

目前提供的免费下载包括:
面向开发人员和设计人员工具Visual Studio Professional  以及Microsoft Visual Studio Express 系列(2010-2013),VS Team Foundation Server Express ,Expression ,Embedded Compact以及一些SDK;面向服务器和应用的Windows Server 2012,SQL server等;面向培训和认证的电子书资料。

VS2013

Visual Studio Professional  2013 已经提供下载,最近收到邮件:

成为首批升级的用户
充分利用您的 DreamSpark 会员权益。获取 Visual Studio Professional 2013。借助一组全新的出色功能,您可以创建新的现代应用程序,这些应用程序可以利用 Windows 平台创新的下一浪潮 (Windows 8.1),同时支持跨所有 Microsoft 平台的设备和服务。
Visual Studio 2013 的集成程度高于之前的任何产品。

如果需要,登录并下载。和之前版本一样,首先下载Secure Download Manager (SDM)并安装,然后下载.SDX 文件,双击下载,完成后进行安装。

down_vs

服务器日志备份的一点小问题

服务器日志备份的一点小问题

前两天一个朋友打电话聊到他遇到的问题:自己动手写的日志备份脚本有问题,当移走日志文件后,应用程序不再写日志到新的文件中,kill 掉应用后才可以..

他的脚本可能是这样的:

mv /log/a_log.trace /log_bak/a_log.trace_xyz 
touch  /log/a_log.trace

相信各位大拿肯定已经知道原因,但是我还在这里说说,为那些可能想知道原因的小童鞋。

 

那么,弄清楚open函数或者sys_open系统调用,知道文件描述符,即使你没有写过C代码,也知道原因了吧!

文件已经被你mv走了,可以原应用还在运行,仍旧保留着原文件的文件描述符,可是文件其实已经不存在了…

解决办法:不要删除或者移走日志文件,清空这个文件就可以了!

cp -p /log/a_log.trace /log_bak/a_log.trace_xyz 
cp /dev/null /log/a_log.trace

再来深入一下吧:

什么是虚拟文件系统?

    VFS(Virtual File System)是 Linux 内核中的一个软件抽象层。它通过一些数据结构及其方法向实际的文件系统如 ext2,vfat 提供接口机制。在其下是实体的文件系统。虚拟文件系统的主要功用,在于让上层的软件,能够用单一的方式,来跟底层不同的文件系统沟通。在操作系统与之下的各种文件系统之间,虚拟文件系统提供了标准的操作接口,让操作系统能够很快的支持新的文件系统。

一切皆是文件!

  一组在逻辑上具有完整意义的信息项的系列。除了普通文件,其他诸如目录、设备、套接字等 也以文件被对待。总之,“一切皆文件”。

文件对象

文件对象是已打开的文件在内存中的表示,主要用于建立进程和磁盘上的文件的对应关系。它由sys_open() 现场创建,由sys_close()销毁。文件对象和物理文件的关系有点像进程和程序的关系一样。当我们站在用户空间来看 待VFS,我们像是只需与文件对象打交道,而无须关心超级块,索引节点或目录项。因为多个进程可以同时打开和操作 同一个文件,所以同一个文件也可能存在多个对应的文件对象。文件对象仅仅在进程观点上代表已经打开的文件,它 反过来指向目录项对象(反过来指向索引节点)。一个文件对应的文件对象可能不是惟一的,但是其对应的索引节点和 目录项对象无疑是惟一的。

 struct file {
    ……
    struct list_head        f_list;        /*文件对象链表*/
    struct dentry          *f_dentry;       /*相关目录项对象*/
    struct vfsmount        *f_vfsmnt;       /*相关的安装文件系统*/
    struct file_operations  *f_op;           /*文件操作表*/
    ……
};

文件I/O

sys_open()系统调用打开或创建一个文件,成功返回该文件的文件描述符。sys_read()系统调用用于从已打开的文件读取数据。如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。

sys_open

 

更多,请再进一步探索..

AIX db2嵌入式SQL(sqc)编译

AIX db2嵌入式SQL(sqc)编译

编译SQC

使用C语言编写嵌入式SQL以访问DB2的程序,DB2预编译器可以将SQL语法直接转换为DB2行时服务应用程序编程接口(API)调用。

bind的主要作用是根据SQC中的SQL语句使用的表和操作指定访问时DB要使用的策略,是一种优化作用,以加快数据访问的速度。

aix_sqc 编译

 

预编译命令:

db2 prep *.sqc bindfile

bindfile参数作用是生成和sqc文件同名的.bnd文件。

接下来就和一般的C程序一样进行编译了,来看看这个简单的Makefile,AIX 编译64位的应用。

CHMOD =chmod 755
RM =rm -f
#export OBJECT_MODE=64
DB2_HOME=/opt/IBM/db2/V9.1
CFLAGS=  -q64 -qchars=signed -I.  -g -I$(DB2_HOME)/include
LDFLAGS = -b64 -g -L $(DB2_HOME)/lib64 -ldb2
DB2 =db2
BINHOME=$(HOME)/batch/bin

CC= xlc_r

#DB CONFIGURE
DBNAME = db2name
USEID = db2user
PASWD = db2pswd

ALL =$(BINHOME)/ApsBatchWS
all:$(ALL)
.SUFFIXES:
.SUFFIXES:.sqc .cpp .c .o
OBJS = dbcons.o serv.o util.o log.o flow.o

.sqc.o:
        $(DB2)  connect to $(DBNAME) user $(USEID) using $(PASWD)
        @$(RM)   *.bnd $*.c
        @$(DB2)  prep $< bindfile
        @$(DB2)  bind $*.bnd
        @$(DB2)  connect reset
        @$(DB2)  terminate
        @$(CC)  $(CFLAGS) -s -c  $*.c
.c.o:
        $(CC) -c $(CFLAGS)  $<
.cpp.o:
        $(CC) -c  $(CFLAGS)  $<

$(ALL) : $(OBJS)
        $(CC) $(CFLAGS)  $(OBJS) $(LDFLAGS) -o  $@
        $(CHMOD)  $@

clean:
        $(RM) *.o dbcon.c dbcons.bnd $(ALL)

看这里还有好多的例子:点击这里查看

sqc的编写方法这里就不再赘述,相关的文章已经太多了。

 

使用cJson[C语言]解析json..

使用cJson[C语言]解析json..

最近很忙,项目的需要,先是搞了搞SOAP,使用gSoap来处理Web service服务端和客户端,确实相当方便,正当搞得莫名其妙时,迎来了五一小长假,回了趟家,一周之后回来,接到的是用json…..JSON?XML?SOAP…?使用gSoap,json-c,libjson?额滴神啊(这其实不是陕西话,原意:MY GOD!)怎么办,搞呗… JSON(JavaScript Object Notation):     http://www.json.org/json-zh.html SOAP(Simple Object Access Protocol ):  http://www.w3school.com.cn/soap/index.asp    http://zh.wikipedia.org/wiki/SOAP 对于出现的所有工具,方法,库可以Google之,我只是把我用json的一些体会记录下来,我只是使用C对简单json报文解析,效率要考虑。 Read more