导航

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

随笔分类

随笔档案

文章档案

相册

2008年4月27日

 

// 格林威治时间转换为北京时间(2000年以后)
// 输入参数 年(2位),月,日,时,分,秒
void Calc( int y, int m, int d, int hh, int mm, int ss )
{
    
int w;        // 星期
    hh += 8;    // 格林威治时间 + 8 小时 = 北京时间

    
if( hh < 24 )    goto l_out;        // 没有跨天,则计算完成

    
///////////// 下面是跨天后的计算 /////////////////////////////
    hh -= 24;
    d 
++;        // 日期加一天

    
switch( m )        // 按月判断
    {
    
case 4:        case 6:                // 跨小月的判断
    case 9:        case 11:
        
if( d > 30 )
        
{
            d 
= 1;    m ++;
        }

        
break;

    
case 1:        case 3:                // 跨大月的判断
    case 5:        case 7:
    
case 8:        case 10:
        
if( d > 31 )
        
{
            d 
= 1;    m ++;
        }

        
break;

    
case 12:                        // 12 月,要判断是否跨年
        if( d > 31 )
        
{
            y 
++;    d = 1;    m = 1;
        }

        
break;

    
case 2:                            // 2 月,要判断是否是闰年
        if( ( (y+2000)%400 == 0 ) ||                        // 能被400整除,一定是闰年
            ( (y+2000)%4 ==0 ) && ( (y+2000)%100 !=0 ) )    // 能被4整除,但不能被100整除,一定是闰年
        {
            
if( d>29 )    // 闰年2月,可以有29号
            {
                m 
= 3;    d = 1;
            }

        }

        
else if( d>28 )    // 非闰年2月,可以有28号
        {
            m 
= 3; d = 1;
        }

        
break;
    }


l_out:    
// 计算完成,开始输出
    printf( "%04d.%02d.%02d - %02d:%02d:%02d", y+2000, m, d, hh, mm, ss);
    
if1 == m )
    
{
        y 
--;
        m 
= 13;
    }

    
else if2 == m )
    
{
        y 
--;
        m 
= 14;
    }


    w 
= y + y/4 + 26 * ( m + 1 ) / 10 + d - 1;
    w 
%= 7;        // 0 表示星期日

    printf ( 
" week=%d ", w );
}
发表于 2008-04-27 22:54 杨老师的茅屋 阅读(1275) | 评论 (4)编辑 收藏

2007年11月18日

CComQIPtr< ISpecifyPropertyPages > spSpecify( m_ax.GetControlUnknown() );
if!spSpecify )    return;

CAUUID pages;
HRESULT hResult 
= spSpecify->GetPages( &pages );
if( FAILED( hResult ) )    return;

CLSID 
* pclsidPages = (CLSID*)_alloca( pages.cElems * sizeof( CLSID ) );
forint i=0; i<(int)pages.cElems; i++ )
    pclsidPages[i] 
= pages.pElems[i];

::CoTaskMemFree( pages.pElems );

IUnknown 
* pObject = m_ax.GetControlUnknown();

OleCreatePropertyFrame( m_hWnd, 
00, L"属性",
    
1&pObject,
    pages.cElems, pclsidPages,
    GetUserDefaultLCID(), 
0, NULL );
发表于 2007-11-18 21:24 杨老师的茅屋 阅读(1551) | 评论 (5)编辑 收藏

2007年10月7日

VC 2003 版本,UNICODE 编译,居然不支持 wsprintf( buf,_T(“%2.1f”),fValue ) 浮点数格式化?!
由于是 API 函数,估计其它版本的编译器可能也会有问题。

发表于 2007-10-07 03:06 杨老师的茅屋 阅读(1779) | 评论 (8)编辑 收藏

2007年4月21日

        一个C/S程序,我自己写的SERVER,我自己写的CLIENT,他们之间使用TCP通讯。某用户使用CLIENT的时候,服务器经常莫名其妙地崩溃,我自己和同事测试,又总找不到问题。今天终于被我逮到了BUG,在我自己的通讯数据中,居然被BT插入了他的数据:“......我的数据......\rBitTorrent Protocol.......我的数据......”导致我服务程序的崩溃。我的天呀!!!!!TNND,BT真变态!!!和某用户联系询问他是否安装了BT下载软件,回答是“yes”。建议他删除BT后,一切正常了。

        代码改进后,程序终于健壮了。

        友情提示:不要想当然地认为TCP数据就能100%地正确地传递到了对方。

                                                            2007-04-21
发表于 2007-04-21 22:47 杨老师的茅屋 阅读(2760) | 评论 (12)编辑 收藏

2006年11月11日

就这个破程序居然浪费了我4个小时来调试! 奉献出来免得大家再走弯路。
SendMMS()
{
    HANDLE hCom 
= CreateFile( _T("COM1"),
        GENERIC_READ 
| GENERIC_WRITE,
        
0, NULL, OPEN_EXISTING, 0, NULL );
    
if( NULL == hCom )    return false;

    DCB dcb;
    ::GetCommState( hCom, 
&dcb );
    dcb.BaudRate 
= 9600;
    dcb.ByteSize 
= 8;
    dcb.Parity 
= NOPARITY;
    dcb.StopBits 
= ONESTOPBIT;

    
if!::SetCommState( hCom, &dcb ) )        return false;
    
if!::PurgeComm( hCom, PURGE_RXCLEAR ) )    return false;
    
    DWORD dw;
    ::WriteFile( hCom, 
"AT\r"3&dw, NULL );
    
// 读串口,判断是否正常
                    
// 切换到中文短信方式
    ::WriteFile( hCom, "AT+WSCL=6,4\r"12&dw, NULL );
    
// 读串口,判断是否正常

    ::WriteFile( hCom, 
"AT+CMGF=1\r"10&dw, NULL );
    
// 读串口,判断是否正常

    WCHAR wszTxt[
500];
    ::wcscpy( wszTxt, L
"hello 你好" );

    
int len = (int)::wcslen(wszTxt);// 字符长度
    forint i=0; i<len; i++ )    // 交换高低字节
        wszTxt[i] = MAKEWORD( HIBYTE(wszTxt[i]), LOBYTE(wszTxt[i]) );

    
char szNumber[50];        // 手机号码,内容长度
    ::sprintf( szNumber, "AT+CMGS=\"13901112233\",%d\r", len*2 );
    ::WriteFile( hCom, szNumber, (DWORD)::strlen( szNumber ), 
&dw, NULL );
    ::Sleep(
500);

    ::WriteFile( hCom, wszTxt, len
*2&dw, NULL );
    ::WriteFile( hCom, 
"\x00\x1a\r", 3, &dw, NULL ); // 结束符
        // 读串口,判断是否正常
       ::CloseHandle( hCom );
       return true;
}
发表于 2006-11-11 03:13 杨老师的茅屋 阅读(2290) | 评论 (8)编辑 收藏

2006年11月1日

#include <Winsock2.h>
#include 
<mstcpip.h>

#pragma comment(lib,
"WS2_32.lib")

typedef 
struct _iphdr
{
    unsigned 
char h_lenver;        //4位首部长度+4位IP版本号
    unsigned char tos;            //8位服务类型TOS
    unsigned short total_len;    //16位总长度(字节)
    unsigned short ident;        //16位标识
    unsigned short frag_and_flags; //3位标志位
    unsigned char ttl;            //8位生存时间 TTL
    unsigned char proto;        //8位协议 (TCP, UDP 或其他)
    unsigned short checksum;    //16位IP首部校验和
    unsigned int sourceIP;        //32位源IP地址
    unsigned int destIP;        //32位目的IP地址
}
IP_HEADER;  

typedef 
struct _tcphdr        //定义TCP首部
{
    USHORT th_sport;        
//16位源端口
    USHORT th_dport;        //16位目的端口
    unsigned int th_seq;
    unsigned 
int th_ack;
    unsigned 
char th_lenres;//4位首部长度/6位保留字
    unsigned char th_flag;    //6位标志位
    USHORT th_win;            //16位窗口大小
    USHORT th_sum;            //16位校验和
    USHORT th_urp;            //16位紧急数据偏移量
}
TCP_HEADER;

typedef 
struct _udphdr        //定义UDP首部
{  
    unsigned 
short uh_sport;
    unsigned 
short uh_dport;
    unsigned 
short uh_len;
    unsigned 
short uh_sum;
}
 UDP_HEADER;  

typedef 
struct _icmphdr        //定义ICMP首部
{  
    BYTE i_type;            
//8位类型
    BYTE i_code;            //8位代码
    USHORT i_cksum;            //16位校验和
    USHORT i_id;            //识别号(一般用进程号作为识别号)
    USHORT i_seq;            //报文序列号
    ULONG timestamp;        //时间戳
}
ICMP_HEADER;

bool DecodeIpPack(const char *,int);    // IP 解包
bool DecodeTcpPack(const char *);        // TCP 解包
bool DecodeUdpPack(const char *);        // UDP 解包
bool DecodeIcmpPack(const char *);        // ICMP 解包
const char * CheckProtocol(int);// 查询协议

int _tmain(int argc, _TCHAR* argv[])
{
    
// 初始化SOCKET
    WSADATA wsaData;
    
int iErrorCode = ::WSAStartup( MAKEWORD(2,1), &wsaData );
    
if( SOCKET_ERROR == iErrorCode )
    
{
        printf( 
"WSAStartup() error. " );
        
return -1;
    }

    
    SOCKET sock 
= ::socket( AF_INET, SOCK_RAW, IPPROTO_IP );
    
if( INVALID_SOCKET == sock )
    
{
        printf( 
"socket() error. " );
        
return -1;
    }


    
//获取本机IP地址
    char szHostName[200];
    iErrorCode 
= ::gethostname( szHostName, sizeof(szHostName) );
    
if( SOCKET_ERROR == iErrorCode )
    
{
        printf( 
"gethostname() error. " );
        
return -1;
    }


    PHOSTENT pHostent 
= ::gethostbyname( szHostName );
    
if( NULL == pHostent )
    
{
        printf( 
"gethostbyname() error. " );
        
return -1;
    }


    SOCKADDR_IN sa;
    sa.sin_family 
= AF_INET;
    memcpy( 
&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length );
    sa.sin_port 
= htons( 60000 );

    iErrorCode 
= ::bind( sock, (PSOCKADDR)&sa, sizeof(sa) );
    
if( SOCKET_ERROR == iErrorCode )
    
{
        printf( 
"bind() error. " );
        
return -1;
    }


    
// 设置 SOCK_RAW 为 SIO_RCVALL,接收所有的 IP 包
    DWORD dwBufferLen[10];
    DWORD dwBufferInLen 
= 1;
    DWORD dwBytesReturned 
= 0;
    iErrorCode 
= ::WSAIoctl( sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen,
        
sizeof( dwBufferLen ), &dwBytesReturned, NULL, NULL );
    
if( SOCKET_ERROR == iErrorCode )
    
{
        printf( 
"Ioctl() error. " );
        
return -1;
    }


    
//侦听IP报文
    while1 )
    
{
        
char package[8 * 1024= 0 };    // 数据缓冲区
        iErrorCode = ::recv( sock, package, sizeof(package), 0 );
        
if( SOCKET_ERROR == iErrorCode )
                printf( 
"recv() error. " );
        
else if!DecodeIpPack( package, iErrorCode ) )    // 解析 IP 包
                printf( "DecodeIpPack() error. " );
    }


    
// ::Closesocket( sock );
    
// ::WSACleanup();
    return 0;
}
  

// 解析 IP 包
bool DecodeIpPack(const char *buf, int iBufSize)
{
    IP_HEADER 
*pIpheader;
    
int iProtocol, iTTL;
    
char szProtocol[12];
    
char szSourceIP[16];
    
char szDestIP[16];
    SOCKADDR_IN saSource, saDest;
    pIpheader 
= (IP_HEADER *)buf;

    
//Check Proto  
    iProtocol = pIpheader->proto;
    ::strcpy( szProtocol, CheckProtocol(iProtocol) );

    
//Check Source IP
    saSource.sin_addr.s_addr = pIpheader->sourceIP;
    ::strcpy( szSourceIP, inet_ntoa(saSource.sin_addr) );

    
//Check Dest IP
    saDest.sin_addr.s_addr = pIpheader->destIP;
    ::strcpy( szDestIP, inet_ntoa(saDest.sin_addr) );
    iTTL 
= pIpheader->ttl;

    
//Output  
    printf( "%s ", szProtocol );
    printf( 
"%s->%s ", szSourceIP, szDestIP );
    printf( 
"bytes=%d TTL=%d ",iBufSize,iTTL );

    
//Calculate IP Header Length
    int iIphLen = sizeof(unsigned long* ( pIpheader->h_lenver & 0x0f );

    
//Decode Sub Protocol:TCP, UDP, ICMP, etc
    switch( iProtocol )
    
{  
    
case IPPROTO_TCP:    DecodeTcpPack( buf + iIphLen );        break;
    
case IPPROTO_UDP:    DecodeUdpPack( buf + iIphLen );        break;
    
case IPPROTO_ICMP:    DecodeIcmpPack( buf + iIphLen );    break;
    
default:    break;
    }

    printf( 
" " );

    
int col = 0;
    
char ascii[17];
    
forint i=0; i<iBufSize; i++ )