置顶随笔 #
2011年6月9日 #
先执行action处理好类里面的变量,然后通过Strust2的标签来获得action类里面变量的值。
<% @ taglib prefix = " s " uri = " /struts-tags " %>
< html >
< head >
< title > Hello World! </ title >
</ head >
< body >
< h2 >< s:property value ="message" /></ h2 >
</ body >
</ html >
在action的类里面有一个message的变量。
方法二、用ValueStack实现
<%
//获取封的ValueStack对象
ValueStack vs=(ValueStack)request.getAttribute("struts.valueStack");
%>
< html >
< head >
< title > Hello World! </ title >
</ head >
< body >
< h2 ><%=vs.findString("message") %></ h2 >
</ body >
</ html >
2010年9月21日 #
原文地址:http://cjmxp007.blog.163.com/blog/static/35473837201061541933667/
2 #define TRANSFORM
3 #include <map>
4 using namespace std;
5 // 是否启用map转换,建议启用
6 // 使用map转换的话,同一个常量字符串不会做两次转换
7 #define TEST_TYPE_MAP
8
9 typedef map<const char*, const char*> strmap;
10
11 class CUtf8String
12 {
13 public:
14 inline CUtf8String(const char* gb2312)
15 {
16 m_bIsConst = true;
17 #ifdef TEST_TYPE_MAP
18 if (m[gb2312])
19 {
20 m_utf8 = m[gb2312];
21 return ;
22 }
23 #endif
24 int buffLen = 0;
25 WCHAR wbuff[5120];
26 MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wbuff, 5120);
27 buffLen = WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, NULL, 0, 0, 0);
28 m_utf8 = new char[buffLen+1];
29 WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, (LPSTR)m_utf8, buffLen, 0, 0);
30 #ifdef TEST_TYPE_MAP
31 m[gb2312] = m_utf8;
32 #endif
33 }
34
35 inline CUtf8String(char* gb2312)
36 {
37 m_bIsConst = false;
38 int buffLen = 0;
39 WCHAR wbuff[5120];
40 MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wbuff, 5120);
41 buffLen = WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, NULL, 0, 0, 0);
42 m_utf8 = new char[buffLen+1];
43 WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, (LPSTR)m_utf8, buffLen, 0, 0);
44 }
45
46 inline ~CUtf8String()
47 {
48 #ifndef TEST_TYPE_MAP
49 if (m_utf8)
50 {
51 delete m_utf8;
52 m_utf8 = 0;
53 }
54 #else
55 if (!m_bIsConst)
56 {
57 if (m_utf8)
58 {
59 delete m_utf8;
60 m_utf8 = 0;
61 }
62 }
63 #endif
64 }
65
66 inline operator char*()
67 {
68 return (char*)m_utf8;
69 }
70 private:
71 const char* m_utf8;
72 bool m_bIsConst;
73 #ifdef TEST_TYPE_MAP
74 static strmap m;
75 #endif
76 };
77
78 class CGb2312String
79 {
80 public:
81 inline CGb2312String(const char* utf8)
82 {
83 #ifdef TEST_TYPE_MAP
84 if (m[utf8])
85 {
86 m_gb2312 = 0;
87 m_gb2312 = m[utf8];
88 }
89 #endif
90 int buffLen = 0;
91 WCHAR wbuff[5120];
92 MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wbuff, 5120);
93 buffLen = WideCharToMultiByte(CP_ACP, 0, wbuff, -1, NULL, 0, 0, 0);
94 m_gb2312 = new char[buffLen+1];
95 WideCharToMultiByte(CP_ACP, 0, wbuff, -1, (LPSTR)m_gb2312, buffLen, 0, 0);
96 #ifdef TEST_TYPE_MAP
97 m[utf8] = m_gb2312;
98 #endif
99 }
100
101 inline CGb2312String(char* utf8)
102 {
103 #ifdef TEST_TYPE_MAP
104 if (m[utf8])
105 {
106 m_gb2312 = 0;
107 m_gb2312 = m[utf8];
108 }
109 #endif
110 int buffLen = 0;
111 WCHAR wbuff[5120];
112 MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wbuff, 5120);
113 buffLen = WideCharToMultiByte(CP_ACP, 0, wbuff, -1, NULL, 0, 0, 0);
114 m_gb2312 = new char[buffLen+1];
115 WideCharToMultiByte(CP_ACP, 0, wbuff, -1, (LPSTR)m_gb2312, buffLen, 0, 0);
116 #ifdef TEST_TYPE_MAP
117 m[utf8] = m_gb2312;
118 #endif
119 }
120
121 inline ~CGb2312String()
122 {
123 #ifndef TEST_TYPE_MAP
124 if (m_gb2312)
125 {
126 delete m_gb2312;
127 m_gb2312 = 0;
128 }
129 #endif
130 }
131
132 inline operator char*()
133 {
134 return (char*)m_gb2312;
135 }
136 private:
137 const char* m_gb2312;
138 #ifdef TEST_TYPE_MAP
139 static strmap m;
140 #endif
141 };
142
143 #ifdef TEST_TYPE_MAP
144 strmap CUtf8String::m;
145 strmap CGb2312String::m;
146 #endif
147 #endif
148
149
150 //===================无聊的分割线==========================
151
152 #define U (CUtf8String)
153
154 #define W (CGb2312String)
155
156 // 使用方法
157 int main(int argc, char* argv[])
158 {
159 // 打印出乱码即为UTF8的编码,方便吧。C++还是确实很强悍的
160 printf("%s", U"你好中国!");
161 }
2010年8月17日 #
Linux的文件系统不像Windows用的是文件的扩展名来区分文件的类型,一般Linux区分文件类型是靠文件属性,也就是二进制文件的最开始的4个字符。
linux是识别文件头和文件属性来打开一个文件的。你就算把可执行的bin命名成.txt,打文件名,照样可以运行,与扩展名无关
用ls -F命令,后买带“*”的就是可执行文件。
下面是一些相关信息的摘录:
linux下,当你使用./xxx运行一个程序时,首先是SHELL来接管你的输入,然后用fork派生子进程,最后用execv系列将你的那个程序的代码交给内核
1。检查你运行的文件的属性,其属性在它的I节点中描述,如果你的那个文件不是可执行的属性,结果就会拒绝执行,如果有可执行的属性,但可执行的权限高于你目前正在使用的用户的权限,拒绝执行
2。检查是SHELL文件吗?如果是,调用相应的SHELL来解析你的这个脚本文件
3。是ELF文件格式吗??是coff文件格式吗?是a.out文件格式吗?如果是其中任何一种,并且当前的LINUX内核都支持这三种文件格式,那么就由操作系统内核分析你的文件格式,去掉文件头信息,将真正的代码,数据等加载进内存(实际过程并不是这样的,只不过为了描述简单,所以省略了很多细节,更多详细说明,请参见内核中的execv系统调用)...
4.等待系统的进程调度,当内核选中你的那个程序的时候,你的那个程序就得到运行了
LINUX下的文件扩展名是形同虚设的,只是一种习惯,为了给用户更好的理解其作用,比如配置文件一般都以.conf结尾,“文本文件”一般都以.txt结尾(主要是为了跟WINDOWS用户习惯相接近),ELF文件不用扩展名,所以当你说可执行文件的时候千万不要说是exe文件,那是很不严格的说法,只说明你仅是一个WINDOWS程序员而已。
Linux的加载程序一般是根据内嵌在可执行文件开头的“magic序列”(一个特殊字节序列)来识别文件,有时也会通过文件名的一些特性。例如,Java编译处理程序可以保证其文件名以.class结尾,并且文件起始前四个字节是 0xcafebabe,这是Java标准所定义的。下面是2.4版本内核在Intel体系下所提供的二进制处理程序,理论上,Linux灵活到足以处理几乎所有的目标文件格式。
2010年8月13日 #
//通过这个简单的实例讲解Windows消息是如何传递的
#include "stdafx.h"
#include <windows.h>
//声明窗口过程函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
//定义一个全局变量,作为窗口类名
TCHAR szClassName[] = TEXT("SimpleWin32");
//应用程序主函数
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR szCmdLine,
int iCmdShow)
{
//窗口类
WNDCLASS wndclass;
//当窗口水平方向的宽度和垂直方向的高度变化时重绘整个窗口
wndclass.style = CS_HREDRAW|CS_VREDRAW;
//关联窗口过程函数
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;//实例句柄
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);//图标
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);//光标
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//画刷
wndclass.lpszMenuName = NULL;//菜单
wndclass.lpszClassName = szClassName;//类名称
//注册窗口类
if(!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("RegisterClass Fail!"),
szClassName, MB_ICONERROR);
return 0;
}
//建立窗口
HWND hwnd;
hwnd = CreateWindow(szClassName,//窗口类名称
TEXT ("The Simple Win32 Application"),//窗口标题
WS_OVERLAPPEDWINDOW,//窗口风格,即通常我们使用的windows窗口样式
CW_USEDEFAULT,//指定窗口的初始水平位置,即屏幕坐标系的窗口的左上角的X坐标
CW_USEDEFAULT,//指定窗口的初始垂直位置,即屏幕坐标系的窗口的左上角的Y坐标
CW_USEDEFAULT,//窗口的宽度
CW_USEDEFAULT,//窗口的高度
NULL,//父窗口句柄
NULL,//窗口菜单句柄
hInstance,//实例句柄
NULL);
ShowWindow(hwnd,iCmdShow);//显示窗口
UpdateWindow(hwnd);//立即显示窗口
//消息循环
MSG msg;
/*
GetMessage()从消息队列中取消息,对取出的消息进行转换(TranslateMessage),
对于能够将虚拟键码转化成字符码的消息,会在消息队列里放一条WM_CHAR消息,
最后将消息发送到相应的消息处理函数进行处理。
循环执行这个处理过程,直到收到WM_QUIT消息,才退出循环,结束程序。
*/
while(GetMessage(&msg,0,0,0))//从消息队列中取消息
{
TranslateMessage (&msg); //转换消息
DispatchMessage (&msg); //派发消息
}
return msg.wParam;
/*---------------GetMessage---------------------------------
GetMessage
函数原型:
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
参数:
lpMsg:一个指向MSG结构的指针,该结构用于存放从消息队列里取出的消息。
hWnd:窗口句柄。如果该参数是非零值,则GetMessage只检索该窗口(也包括其子窗口)消息,如果为零,则GetMessage检索整个进程内的消息。
wMsgFilterMin:指定被检索的最小消息值,也就是消息范围的下界限参数。
wMsgFilterMax:上界限参数。如果wMsgFilterMin和wMsgFilterMax都为零,则不进行消息过滤,GetMessage检索所有有效的消息。
返回值:
GetMessage检索到WM_QUIT消息,返回值是零;其它情况,返回非零值。
函数功能:
这个API函数用来从消息队列中“摘取”一个消息,放到lpMsg所指的变量里。(注:如果所取窗口的消息队列中没有消息,则程序会暂停在GetMessage(…) 函数里,不会返回。)
再通俗一点讲解GetMessage函数:
当程序执行GetMessage()的时候,会检查消息队列,如果有消息在消息队列里,它取出该消息,将该消息填充到lpMsg所指的MSG结构,并返回TRUE值。如果此时消息队列里没有消息(消息队列为空),它会将线程阻塞,也就是将控制权交给系统,直到消息队列中有内容时,才唤醒线程继续执行。
对于GetMessage()函数,还有一点需要说明,就是当从消息队列中取出的消息是WM_QUIT时,函数返回值是0。我们一般利用这一点退出消息循环,结束程序。
---------------------------------------------------------------*/
/*------------------TranslateMessage---------------------
TranslateMessage
函数原型:
BOOL TranslateMessage(CONST MSG*lpMsg);
参数:
IpMsg:指向MSG结构的指针,该结构是函数GetMessage或PeekMessage从消息队列里取得的消息。
函数功能:
该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
什么是虚拟键码呢?Windows为了方便输入管理,减少程序对设备的依赖性,将键盘上所有的按键都用一个两位十六进制数对应,这些数称为虚拟键码。虚拟键码一般以VK_开头,如:Esc键对应的虚拟键码是VK_ESCAPE;空格键对应的虚拟键码是VK_SPACE;VK_LWIN与左边的Windows徽标键相对应。
当一个按键被按下时,会触发WM_KEYDOWN消息, WM_KEYDOWN消息的wParam参数值就是虚拟键值。通过这个值就可以判断哪个键被按下了。
为什么我们要把虚拟键码转换为字符码呢?
比如我们按下了‘A’键,此时我们得到的字符可能是‘A’,也可能是小写的‘a’,这由当时的大写状态(Caps Lock)以及是否同时按下了Shift键有关。TranslateMessage()函数的作用就是不用我们考虑这些问题,而是根据这些情况,自动返回一个ASCII码值,以方便用户使用。
并不是所有的虚拟键码值都会Translate成字符码。字母、数字键都有字符码相对应,而像方向箭头键、F1—F12功能键这些按键就没有字符码相对应。当虚拟键码需要转化成字符码时,TranslateMessage()函数就在消息队列里放一条WM_CHAR消息,WM_CHAR消息的wParam参数值就是转换后的ASCII码值。
-------------------------------------------*/
/*--------------------DispatchMessage-------------------
DispatchMessage
函数原型:
LONG DispatchMessage(CONST MSG *lpmsg);
函数功能:
它的作用很简单,就是分派消息到窗口的消息处理函数去执行。
-------------------------------------------*/
/*-----------------PeekMessage-------------
PeekMessage
函数原型:
BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
参数:
lpMsg、hWnd、wMsgFilterMin、wMsgFilterMax这四个参数的意义和GetMessage对应参数的意义相同,在此不再赘述。
wRemoveMsg:这个参数决定读消息时是否删除消息,可选值有PM_NOREMOVE和PM_REMOVE。如果您选PM_NOREMOVE,执行该函数后消息仍然留在消息队列(我称为读消息);如果您选PM_REMOVE,执行该函数后将在消息队列中移除该消息(同GetMessage())。
返回值:
消息队列中有消息,返回值为TRUE;消息队列中没有消息,返回值为FALSE。
函数功能:
PeekMessage()也是从消息队列中取消息,但它是GetMessage()不同,主要在以下两点:
(一)、GetMessage()只能从消息队列中取走消息,也就是说,GetMessage()执行后,该消息将从消息队列中移除。
PeekMessage()可以从消息队列中取走消息。也可以读消息,让消息继续留在消息队列里。
(二)、当消息队列中没有消息时,GetMessage()将会阻塞线程,等待消息;而PeekMessage()与GetMessage()不同,它执行后会立刻返回,消息队列中有消息时,返回值为TRUE;消息队列中没有消息时,返回值为FALSE。
------------------------------------*/
/*-------------------PeekMessage版的消息循环---------------------------
//消息循环
MSG msg;
while(true)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //从消息队列中取消息
{
if(msg.message == WM_QUIT)
break;
TranslateMessage (&msg); //转换消息
DispatchMessage (&msg); //派发消息
}
else
WaitMessage();
} //End of while(true)
*/
/*------------------WaitMessage--------------------------
WaitMessage
函数原型:
BOOL WaitMessage(VOID);
函数功能:
这个函数的作用是当消息队列中没有消息时,将控制权交给其它线程。该函数将会使线程挂起,直到消息队列中又有新消息。
这个函数专门和PeekMessage配合使用,当消息队列中没有消息时,挂起线程,等待消息队列中新消息的到来,这样可以减轻CPU的运算负担。
--------------------------------------------------*/
}
//消息处理函数
//参数:窗口句柄,消息,消息参数,消息参数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//处理感兴趣的消息
switch (message)
{
case WM_DESTROY:
//当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
PostQuitMessage(0);
return 0;
}
//其他消息交给由系统提供的缺省处理函数
return ::DefWindowProc (hwnd, message, wParam, lParam);
}
2010年6月3日 #
首先要添加引用
#pragma comment (lib, "ws2_32.lib") //lib
调用的代码:
{
std::string errMsg;//错误信息记录
WSADATA wsaData;
SOCKET sock;
SOCKADDR_IN tcpaddr;
hostent * remoteHost;
char host[] = {"192.168.1.1"}; //主机名就直接写了
int Ret,l;
BOOL done;
int port = 80;
int chars = 0;
char buffer[1024];
if( (Ret = WSAStartup(MAKEWORD(1,1), &wsaData) ) != 0 )
{
errMsg+="WSAStartup failed with error "+Ret;
return 1;
}
if( (remoteHost = gethostbyname(host)) == NULL ) //通过主机名获取地址
{
errMsg+="gethostbyname error!\n";
return 1;
}
sock = socket (AF_INET, SOCK_STREAM, 0);
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_port = htons( (unsigned short)port );
tcpaddr.sin_addr.s_addr = *((unsigned long *)*remoteHost->h_addr_list); //转换地址
if( connect(sock, (const sockaddr * )&tcpaddr, sizeof(tcpaddr)) )
{
errMsg+="connect error!";
return 1;
}
//这里是要发送的http头部
SendString(sock,"GET / HTTP/1.1\r\n");
SendString(sock,"Host:192.168.1.1\r\n");
SendString(sock,"Accept: */*\r\n");
SendString(sock,"User-Agent: Mozilla/4.0");
SendString(sock,"(compatible; MSIE 7.00; Windows 98)\r\n");
SendString(sock,"Connection:Keep-Alive\r\n");
SendString(sock,"\r\n");
SendString(sock,"\r\n");//最后要加空行
done = FALSE;
//FILE * fp;
//fp = fopen("1.txt","w");
//打印并保存http响应的头部
std::string str;
while(!done)
{
l = recv(sock,buffer,1,0);//一个字节一个字节的接受HTTP头
str+=*buffer;
if(l<0)
done=TRUE;
switch(*buffer)
{
case '\r':
break;
case '\n'://判断HTTP头是否接受完毕
if(chars==0)
done = TRUE;
chars=0;
break;
default:
chars++;
break;
}
printf("%c",str);
//fputc(buffer[0],fp);
}
//接收正文部分
int sum = 0;
do
{
l = recv(sock,buffer,1024,0);
if( l < 0 )
break;
sum += l;
str.append(buffer,l);
//*(buffer + l) = 0;
//fputs(buffer,fp);
} while( l > 0 );
//这里输出正文部分大小,发现其实和响应消息头部的Content-length大小是一样的
//这样就可以检查是否接受完毕
printf("sum = %d\n",sum);
closesocket(sock);
if( WSACleanup() == SOCKET_ERROR )
{
errMsg+="WSACleanup failed with error "+WSAGetLastError();
}
rest=str;
return 1;
}
void SendString(SOCKET sock,LPCSTR str)
{
send(sock,str,strlen(str),0);
}
2010年6月2日 #
2010年5月28日 #
2010年5月12日 #
2010年2月22日 #
2010年2月8日 #
2009年11月6日 #
2009年11月3日 #
2009年9月23日 #
2009年5月20日 #
2009年3月30日 #
2009年3月23日 #
2009年3月17日 #
2008年9月2日 #
2008年5月8日 #
2007年8月14日 #
2007年7月24日 #
2007年7月11日 #
2007年1月4日 #


