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);
if( 1 == m )

{
y --;
m = 13;
}
else if( 2 == m )

{
y --;
m = 14;
}

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

printf ( " week=%d ", w );
}
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 ) );
for( int i=0; i<(int)pages.cElems; i++ )
pclsidPages[i] = pages.pElems[i];

::CoTaskMemFree( pages.pElems );

IUnknown * pObject = m_ax.GetControlUnknown();

OleCreatePropertyFrame( m_hWnd, 0, 0, L"属性",
1, &pObject,
pages.cElems, pclsidPages,
GetUserDefaultLCID(), 0, NULL );
2007年10月7日
VC 2003 版本,UNICODE 编译,居然不支持 wsprintf( buf,_T(“%2.1f”),fValue ) 浮点数格式化?!
由于是 API 函数,估计其它版本的编译器可能也会有问题。
2007年4月21日
一个C/S程序,我自己写的SERVER,我自己写的CLIENT,他们之间使用TCP通讯。某用户使用CLIENT的时候,服务器经常莫名其妙地崩溃,我自己和同事测试,又总找不到问题。今天终于被我逮到了BUG,在我自己的通讯数据中,居然被BT插入了他的数据:“......我的数据......\rBitTorrent Protocol.......我的数据......”导致我服务程序的崩溃。我的天呀!!!!!TNND,BT真变态!!!和某用户联系询问他是否安装了BT下载软件,回答是“yes”。建议他删除BT后,一切正常了。
代码改进后,程序终于健壮了。
友情提示:不要想当然地认为TCP数据就能100%地正确地传递到了对方。
2007-04-21
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);// 字符长度
for( int 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月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报文
while( 1 )

{

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];
for( int i=0; i<iBufSize; i++ )
![]()