网络服务器软件开发/中间件开发,关注ACE/ICE/boost

C++博客 首页 新随笔 联系 聚合 管理
  152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks

#

       1.新建查询语句文件query.sql,内容如下:
--------------------------------------分割线----------------------------------------
         use appdb;
         set names utf8;
         select FeedID, City , Message  from Feed limit 1000;
--------------------------------------分割线----------------------------------------
上面的set names utf8语句是设施当前使用的编码,如果编码和数据库的编码不一致,会出现乱码
      2.执行如下:
     [root@proxy tianqg]# mysql -uroot -p < query.sql > query.txt
回车,输入密码,在当前目录下会产生查询结果文件query.txt
      这些语句以前都是非常熟悉的,昨天有人问起,一时没有给出准确的回答,命令行操作这种东西是容易忘记的,还是记下来备忘吧
posted @ 2011-01-19 09:55 true 阅读(1397) | 评论 (0)编辑 收藏

      有个存储过程,功能是:根据用户名查询非好友的ID,代码如下:
begin

  select UserID  from  Users
    where
    UserID 
!= pUserID and
    Users.UserID  not 
in
    (
        select FriendID from Users_Friend where Users_Friend.UserID 
= pUserID and DeleteFlag = 0
    )
    and
    Users.Name like BINARY  concat(
'%',pUserName,'%')  ;

end
 其中,pUserID是搜索者的UID,pUserName是要搜索的用户名。今天发现这个存储过程非常慢,分析结论是:not in 后面的select子查询是每次都执行的,这出乎意料!mysql难道不能优化掉这样的查询吗?
      后来用了临时表的方案,如下:
begin

    Create TEMPORARY  Table  IF NOT EXISTS temp(FriendID 
int );
    insert into temp(FriendID) select FriendID from Users_Friend where Users_Friend.UserID 
= pUserID and DeleteFlag = 0;

      select UserID  from  Users
    where
    UserID 
!= pUserID and
    Users.UserID  not 
in
    (
        select FriendID from temp
    )
    and
    Users.Name like BINARY  concat(
'%',pUserName,'%')  ;

    drop TEMPORARY  table temp;
end

问题较好的解决了,因为临时表temp中保存的都是好友的ID,非常快,不用每次都去执行好友的筛选逻辑。另外一种方式是:将好友ID作为参数传递到存储过程中,在程序外面查询好友,但要改动程序。
 
posted @ 2011-01-13 13:05 true 阅读(2923) | 评论 (0)编辑 收藏

     摘要: 最近几天一直在思考一个问题:我们需要什么样的网络基础开发包?libevent,asio,ace,还是自己封装?Buffer类,内存池  阅读全文
posted @ 2011-01-13 00:51 true 阅读(3139) | 评论 (16)编辑 收藏

已经非常的陌生了,没有网络几乎写不了代码了,准备写个自用的抓包工具,可以指定某个应用来抓包,这样抓到的包分析起来更具有针对性,常用工具wireshark虽然支持过滤规则,但是对走多协议的应用,比如tcp,udp,http都用的应用过滤起来比较吃力,WPE也不太合适,我想集成一些实用小工具,如网络字节序的转换,UTF8和GB的转换等,如此则可以快速分析协议,所以索性自己写个吧,网络抓包这块是做服务器的基本功,已经搞定了,界面的布局和实现方面还没有确定,不用MFC好多年,希望这次尝试算是一个新的开始。

posted @ 2011-01-06 23:42 true 阅读(527) | 评论 (0)编辑 收藏

     自从做公司的SNS社区以来,写了不少的C#代码,与C++相比,C#是易于使用的,开发效率提高很多倍,其中印象比较深刻的是,在一个C#工程中,可以通过向导添加配置文件,默认文件名为App.Config,是XML格式,一般内容为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
     
    
<appSettings>

        
<add key="Ip" value="localhost"/>
        
<add key="Port" value="8888"/>
        
<add key="ServiceName" value="Indexer"/>


    
</appSettings>
    
</configuration>
通过在appSettings里面添加add元素,即可实现通常的配置功能,更重要的是,可以进一步扩展为多级的树形结构,与Ini格式相比,更直观,可读性更强,下面是基于CMarkup(http://www.firstobject.com/)的一个简单实现:
头文件如下:
#pragma once

#include 
<string>
#include 
<map>


class AppConfig
{
public:
    AppConfig(
void);
    
~AppConfig(void);

    
int        GetInt(std::string key);
    std::
string    GetString(std::string key);
private:
    std::map
<std::string,std::string> config_map_;
}
;
 
extern AppConfig appConfig;
源文件如下:

#include 
"AppConfig.h"
#include 
"Markup.h"

AppConfig appConfig;


AppConfig::AppConfig(
void)
{
    CMarkup parser;
    
if (!parser.Load( "App.Config"  ))
    
{
        
return;        
    }

    
if (parser.FindChildElem("appSettings"))
    
{
        parser.IntoElem();
        
while (parser.FindChildElem("add"))
        
{
            std::
string key = parser.GetChildAttrib("key");
            std::
string value = parser.GetChildAttrib("value");
            config_map_[key] 
= value;
        }

        parser.OutOfElem();
    }

    
}


AppConfig::
~AppConfig(void)
{
}


int AppConfig::GetInt( std::string key )
{
    
if (config_map_.find(key) != config_map_.end())
    
{
        
return atoi(config_map_[key].c_str());
    }

    
else
    
{
        
return 0;
    }

}


std::
string AppConfig::GetString( std::string key )
{
    
if (config_map_.find(key) != config_map_.end())
    
{
        
return config_map_[key];
    }

    
else
    
{
        
return "";
    }

}

测试代码为:
// MarkupTest.cpp : 定义控制台应用程序的入口点。
//

#include 
"stdafx.h"

#include 
"AppConfig.h"
#include 
<iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{    
    cout 
<< appConfig.GetString("Ip")  << "-----" << appConfig.GetInt("Port")  << "----" << appConfig.GetString("ServiceName"<< endl;
    
return 0;
}


posted @ 2010-12-29 00:25 true 阅读(2501) | 评论 (0)编辑 收藏

         CDR可以提供对基本数据类型如int,short,double,string等的序列化机制,简单包装后即可担当RPC中的序列化角色。
#include <iostream>
#include 
<string>
#include 
<ace/OS.h>
#include 
<ace/String_Base.h>
#include 
<ace/CDR_Stream.h>
using namespace std;
#pragma comment(lib,
"aced")

int main(int argc, char* argv[])
{
    cout 
<< "ACE CDR demo" << endl;

    ACE_CString sAppName 
= "CDRDemo",sAppName2;
    ACE_CDR::Long nUID 
= 123456,nUID2;
    ACE_CDR::Float nfPosX 
= 120.51,nfPosX2;
    ACE_CDR::Double ndScore 
= 120.51,ndScore2;
    ACE_CString sDummy 
= "another string",sDummy2;
    ACE_CDR::Short  nsLength 
= 10,nsLength2;

    ACE_OutputCDR outCDR(ACE_DEFAULT_CDR_BUFSIZE);    
    
    outCDR 
<< nUID;
    outCDR 
<< nfPosX;
    outCDR 
<< ndScore;
    outCDR 
<< sAppName;//写字符串时,先写入字符串的长度
    outCDR << sDummy;
    outCDR 
<< nsLength;

    cout 
<< "OutputCDR size = " << outCDR.length() << endl;

    
//可以通过socket发送出去,而在服务端进行下面的解析
    
//1.ACE_Message_Block *ACE_OutputCDR::begin (void)
    
//2.通过ACE_SOCK_Stream发送出去    

    ACE_InputCDR inCDR(outCDR);

    inCDR 
>> nUID2;
    inCDR 
>> nfPosX2;
    inCDR 
>> ndScore2;
    inCDR 
>> sAppName2;
    inCDR 
>> sDummy2;
    inCDR 
>> nsLength2;
        

    ACE_ASSERT(nUID 
== nUID2);
    ACE_ASSERT(nfPosX 
== nfPosX2);
    ACE_ASSERT(ndScore 
== ndScore2);
    ACE_ASSERT(sAppName 
== sAppName2);
    ACE_ASSERT(sDummy 
== sDummy2);
    ACE_ASSERT(nsLength 
== nsLength2);

    cout 
<< "test ok." << endl;

    
return 0;
}

假若有如下的demo.idl,内容如下:

      struct user_info
      {
            int user_id;
            string user_name;            
      }
利用idl_gen生成代码时:
      (1)如果是侵入式的方案,则生成user_info类时,自动添加成员OutputCDR和InputCDR成员,并添加pack(ACE_Message_Block &* msg)和parse(ACE_Message_Block * msg)成员函数,在pack和parse里面,调到对于的CDR类,按照类中数据成员的声明顺序依次序列化,反序列化
      (2)如果是非侵入式方案,则生成user_info类时,生成独立函数的pack(user_info& info, ACE_Message_Block &* msg)和parse(user_info& info,ACE_Message_Block * msg),pack和parse的函数实现同上
posted @ 2010-12-26 09:52 true 阅读(3160) | 评论 (2)编辑 收藏

      wireshark(http://www.wireshark.org/)是我经常用到的抓包工具,这对于网络程序的调试至关重要,特别是客户端人员和服务端人员都认为自己的代码没问题时,wireshark本身是开源的,在windows平台下基于 winpcap(http://www.winpcap.org/)开发的,安装wireshark的时候,会提示在线安装winpcap,今天在笔记本上用VS2008,编译了Examples-pcap下面的basic_dump和basic_dump_ex,不曾想到的是抓不到包,甚是奇怪,因为用wireshark抓包是可以的,因此怀疑是不是哪个参数设施不对,终于比对wireshark,得出结论:将pcap_open_live的第四个参数设为0,即不能打开混杂模式,

if ((adhandle= pcap_open_live(d->name, // name of the device
        65536,   // portion of the packet to capture.
           // 65536 grants that the whole packet will be captured on all the MACs.
        0,    // promiscuous mode (nonzero means promiscuous)
        1000,   // read timeout
        errbuf   // error buffer
        )) == NULL)
 {
  fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
  /* Free the device list */
  pcap_freealldevs(alldevs);
  return -1;
 }
posted @ 2010-12-22 21:59 true 阅读(4281) | 评论 (3)编辑 收藏

   手册上的说明:
   

   UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)

If called with no argument, returns a Unix timestamp (seconds since '1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP() is called with a date argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00' UTC. date may be a DATE string, a DATETIME string, a TIMESTAMP, or a number in the format YYMMDD or YYYYMMDD. The server interprets date as a value in the current time zone and converts it to an internal value in UTC. Clients can set their time zone as described in Section 5.11.8, “MySQL Server Time Zone Support”.


      这里的UNIX_TIMESTAMP()的返回值和C函数time(NULL)的返回值含义一样,
  mysql> select UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
|       1292815556 |
+------------------+
1 row in set

mysql> select FROM_UNIXTIME(1292815556);
+---------------------------+
| FROM_UNIXTIME(1292815556) |
+---------------------------+
| 2010-12-20 11:25:56       |
+---------------------------+
1 row in set

posted @ 2010-12-20 12:01 true 阅读(466) | 评论 (0)编辑 收藏


终于碰到这个问题了,原文链接:http://hi.baidu.com/zzy_cqok/blog/item/46ee33998777f3056f068c2b.html

vs2008调试后控制台窗口关不了2010-07-29 16:19
最近用Visual Studio 2008 写一些控制台程序,调试后的时候,当走到完成的时候,这个控制台程序的窗口就关不了了。再调试的时候就会出现一个新的控制台程序。
在任务管理器还可以看到这个窗口,但是关不掉了。感觉这个控制台程序已经失控了。
虽然这个对电脑运行没有影响,但还是很不爽。而且最后关机还有问题,导致不能关机。
找到一些相关的网页也讨论的,最后结论是windows的一个更新KB978037导致cress.exe出了一些问题。
解决办法:删除KB978037更新,删除的办法是在控制面板的添加或删除程序面板里,勾选显示更新,找到KB978037更新,删除。
附别人的讨论记录:http://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e6d4a4f5-7002-401a-90e1-6174d7f9e3ca/
 
posted @ 2010-12-12 13:16 true 阅读(1091) | 评论 (0)编辑 收藏

http://www.boostpro.com/download/
目前只有windows平台的,而且是32位
posted @ 2010-12-06 12:08 true 阅读(420) | 评论 (0)编辑 收藏

仅列出标题
共15页: 1 2 3 4 5 6 7 8 9 Last