存档

2011年11月 的存档

javascript 格式化

2011年11月20日 4 条评论

http://www.css88.com/tool/js_beautify/

http://jsbeautifier.org/

http://tool.chinaz.com/Tools/JsFormat.aspx

都是http://jsbeautifier.org/提供的

分类: jquery/JS 标签:

vmware用桥接,vm获取不到IP地址

2011年11月18日 没有评论

原因是主机有多个网卡,在Edit – Virtual Network Editor里面设置 VMnet0(或者已经有bridge类型的)为bridge类型,bridge to指定的网卡

分类: 虚拟机 标签:

转:用Python干实事(一)自动修改Windows的IP、网关和DNS设置

2011年11月18日 没有评论

最近由于工作和学习需要在家里装上了小区宽带(80元/月),整个小区共享30M带宽,开始以为会很慢,结果用起来速度还是挺不错的。不说废话了,言归正传,由于家里和公司的IP设置不一样(都是静态的),每次回家和去公司都需要手动改IP,改了几天嫌麻烦就想写个小程序可以自动设置IP,只需要双击一下程序就搞定IP设置。就上网搜了一下,大概有这么几种方法:使用Windows的脚本(http://www.microsoft.com/china/technet/community/scriptcenter/topics/networking/default.mspx)或者编写一个批处理使用netsh命令来完成这个任务,当然用C/C++也是绝对可以的。不过为了练习一下Python和想更多了解一下Python,所以就决定用Python来写个自动设置IP的程序。参考文章:http://www.pconline.com.cn/pcedu/empolder/gj/vc/0508/694212.html
代码如下:

1 # FileName: modify_ip.py
  2 # Author  : qujinlong
  3 # Email   : qujinlong123@gmail.com
  4 # Date    : 2007-06-20
  5 
  6 import _winreg
  7 
  8 from ctypes import *
  9 
 10 # MessageBox = windll.user32.MessageBoxA
 11 # MessageBox(0, 'Welcome!', 'Hello', 0)
 12 
 13 print '正在修改IP,请稍后'
 14 
 15 netCfgInstanceID = None
 16 
 17 hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, \
 18                        r'System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}')
 19 
 20 keyInfo = _winreg.QueryInfoKey(hkey)
 21 
 22 # 寻找网卡对应的适配器名称 netCfgInstanceID
 23 for index in range(keyInfo[0]):
 24     hSubKeyName = _winreg.EnumKey(hkey, index)
 25     hSubKey = _winreg.OpenKey(hkey, hSubKeyName)
 26 
 27     try:
 28         hNdiInfKey = _winreg.OpenKey(hSubKey, r'Ndi\Interfaces')
 29         lowerRange = _winreg.QueryValueEx(hNdiInfKey, 'LowerRange')
 30 
 31         # 检查是否是以太网
 32         if lowerRange[0] == 'ethernet':
 33             driverDesc = _winreg.QueryValueEx(hSubKey, 'DriverDesc')[0]
 34             # print 'DriverDesc: ', driverDesc
 35             netCfgInstanceID = _winreg.QueryValueEx(hSubKey, 'NetCfgInstanceID')[0]
 36             # print 'NetCfgInstanceID: ', netCfgInstanceID
 37             break
 38 
 39         _winreg.CloseKey(hNdiInfKey) # 关闭 RegKey
 40     except WindowsError:
 41         print r'Message: No Ndi\Interfaces Key'
 42 
 43     # 循环结束,目前只提供修改一个网卡IP的功能
 44     _winreg.CloseKey(hSubKey)
 45 
 46 _winreg.CloseKey(hkey)
 47 
 48 if netCfgInstanceID == None:
 49     print '修改IP失败 - 没有找到网络适配器'    
 50     exit()
 51 
 52 # print netCfgInstanceID
 53 
 54 # 通过修改注册表设置IP
 55 strKeyName = 'System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\' + netCfgInstanceID
 56 
 57 # print strKeyName
 58 
 59 hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, \
 60                        strKeyName, \
 61                        0, \
 62                        _winreg.KEY_WRITE)
 63 
 64 # 定义需要修改的IP地址、子网掩码、默认网关和DNS等
 65 ipAddress = ['192.168.1.135']
 66 subnetMask = ['255.255.255.0']
 67 gateway = ['192.168.1.10']
 68 dnsServer = ['202.106.196.115', '202.106.0.20']
 69 
 70 try:
 71     _winreg.SetValueEx(hkey, 'IPAddress', None, _winreg.REG_MULTI_SZ, ipAddress)
 72     _winreg.SetValueEx(hkey, 'SubnetMask', None, _winreg.REG_MULTI_SZ, subnetMask)
 73     _winreg.SetValueEx(hkey, 'DefaultGateway', None, _winreg.REG_MULTI_SZ, gateway)
 74     _winreg.SetValueEx(hkey, 'NameServer', None, _winreg.REG_SZ, ','.join(dnsServer))
 75 except WindowsError:
 76     print 'Set IP Error'
 77     exit()
 78 
 79 _winreg.CloseKey(hkey)
 80 
 81 # 调用DhcpNotifyConfigChange函数通知IP被修改
 82 DhcpNotifyConfigChange = windll.dhcpcsvc.DhcpNotifyConfigChange
 83 
 84 inet_addr = windll.Ws2_32.inet_addr
 85 
 86 # DhcpNotifyConfigChange 函数参数列表:
 87 # LPWSTR lpwszServerName,  本地机器为None
 88 # LPWSTR lpwszAdapterName, 网络适配器名称
 89 # BOOL bNewIpAddress,      True表示修改IP
 90 # DWORD dwIpIndex,         表示修改第几个IP, 从0开始
 91 # DWORD dwIpAddress,       修改后的IP地址
 92 # DWORD dwSubNetMask,      修改后的子码掩码
 93 # int nDhcpAction          对DHCP的操作, 0 - 不修改, 1 - 启用, 2 - 禁用
 94 DhcpNotifyConfigChange(None, \
 95                        netCfgInstanceID, \
 96                        True, \
 97                        0, \
 98                        inet_addr(ipAddress[0]), \
 99                        inet_addr(subnetMask[0]), \
100                        0)
101 
102 print '修改IP结束'
103

Python写起来真是清爽啊,没有一点拖泥带水,没有任何的指针、引用传进传出,也不用搞复杂的类型变来变去。
代码中用到了winreg模块去读取和修改Windows的注册表,还用到了ctypes去链接DLL调用Windows API。
至于程序所使用的修改IP的原理在参考文章中描述的很清楚,有什么问题可以mail我。
程序以简单起见,在修改IP的过程中一些例外情况并没有处理,呵呵,只要自己能正常使用就行了:)
等过两天有时间写个界面程序,可以设置和读取IP配置,类似于Windows的网络设置的UI界面。

不喜欢上面代码中有行号的朋友可以下载这个源程序:自动修改IP的Python程序

改进性能从点滴做起:
(1).由于Python中的字符串是不可变的,每次使用“+”号创建新字符串会拷贝原有的字符串构造新的字符串,降低性能,所以应避免使用“+”号构造字符串(类似于Java)。据此可将上面的一句代码更改如下:
strKeyName = r’System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s’ % netCfgInstanceID
(2).待续…

(2007-06-21增加)
经笨笨狗的提示,研究了一下在Python中使用WMI来实现这个功能,比上面的修改注册表方法简单的太多,而且比使用Windows的脚本也简单了一点。先将新版本的代码贴出来(其中使用了Tim Golden对WMI的包装模块,并且这个模块使用了Python for Windows extensions(pywin32)):

1 # -*- coding: cp936 -*-
 2 
 3 # FileName: modify_ip(wmi).py
 4 # Author  : qujinlong
 5 # Email   : qujinlong123@gmail.com
 6 # Date    : 2007-06-21
 7 
 8 import wmi
 9 
10 print '正在修改IP,请稍后'
11 
12 wmiService = wmi.WMI()
13 
14 colNicConfigs = wmiService.Win32_NetworkAdapterConfiguration(IPEnabled = True)
15 
16 #for objNicConfig in colNicConfigs:
17 #    print objNicConfig.Index
18 #    print objNicConfig.SettingID
19 #    print objNicConfig.Description
20 #    print objNicConfig.IPAddress
21 #    print objNicConfig.IPSubnet
22 #    print objNicConfig.DefaultIPGateway
23 #    print objNicConfig.DNSServerSearchOrder
24 
25 if len(colNicConfigs) < 1:
26     print '没有找到可用的网络适配器'
27     exit()
28 
29 # 获取第一个网络适配器的设置
30 objNicConfig = colNicConfigs[0]
31 
32 #for method_name in objNicConfig.methods:
33 #   method = getattr(objNicConfig, method_name)
34 #   print method
35 
36 arrIPAddresses = ['192.168.1.136']
37 arrSubnetMasks = ['255.255.0.0']
38 arrDefaultGateways = ['192.168.1.1']
39 arrGatewayCostMetrics = [1]
40 arrDNSServers = ['192.168.1.3', '202.106.46.151', '202.106.0.20']
41 intReboot = 0
42 
43 returnValue = objNicConfig.EnableStatic(IPAddress = arrIPAddresses, SubnetMask = arrSubnetMasks)
44 if returnValue[0] == 0:
45     print '  成功设置IP'
46 elif returnValue[0] == 1:
47     print '  成功设置IP'
48     intReboot += 1
49 else:
50     print '修改IP失败(IP设置发生错误)'
51     exit()
52 
53 returnValue = objNicConfig.SetGateways(DefaultIPGateway = arrDefaultGateways, GatewayCostMetric = arrGatewayCostMetrics)
54 if returnValue[0] == 0:
55     print '  成功设置网关'
56 elif returnValue[0] == 1:
57     print '  成功设置网关'
58     intReboot += 1
59 else:
60     print '修改IP失败(网关设置发生错误)'
61     exit()
62 
63 returnValue = objNicConfig.SetDNSServerSearchOrder(DNSServerSearchOrder = arrDNSServers)
64 if returnValue[0] == 0:
65     print '  成功设置DNS'
66 elif returnValue[0] == 1:
67     print '  成功设置DNS'
68     intReboot += 1
69 else:
70     print '修改IP失败(DNS设置发生错误)'
71     exit()
72 
73 if intReboot > 0:
74     print '需要重新启动计算机'
75 else:
76     print ''
77     print '  修改后的配置为:'
78     print '  IP: ', ', '.join(objNicConfig.IPAddress)
79     print '  掩码:', ', '.join(objNicConfig.IPSubnet)
80     print '  网关:', ', '.join(objNicConfig.DefaultIPGateway)
81     print '  DNS:', ', '.join(objNicConfig.DNSServerSearchOrder)
82 
83 print '修改IP结束'
84

简单了很多,呵呵

转自: http://www.blogjava.net/qujinlong123/archive/2007/06/20/125434.html

分类: Python 标签:

Using the Windows 32 API from Python

2011年11月18日 没有评论

具体请看这里

http://vermeulen.ca/python-win32api.html

分类: Python 标签:

转:不重起Windows直接更改IP地址的三种方法

2011年11月17日 1 条评论

有很多网友都遇到过更改IP地址但是要重启机器的问题,在这里,为大家介绍几种不重启Windows直接更改IP地址的方法。首先是调用DhcpNotifyConfigChange的方法,后面还有修改注册表跟使用”iphlpapi”的方法。

  一、未公开函数:DhcpNotifyConfigChange

  设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重新启动系统才能生效,而AddIPAddress函数只能添加IP而不是更改当前的IP,我们在Windows NT/2000界面上操作不需要重新启动就可以生效,那系统到底做了什么额外的工作才使IP设置直接生效呢?笔者通过跟踪explorer.exe中API的调用发现在netcfgx.dll中调用了dhcpcsvc.dll中一个未公开的API:DhcpNotifyConfigChange,现将不重新启动WINDOWS直接更改IP地址的详细方法介绍如下:

  1、获取适配器名称

  这里指的适配器名称要区别于适配器描述,比如我的一块网卡,适配器描述是:Realtek RTL8139(A) PCI Fast Ethernet Adapter,适配器名称为:{66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}。获取适配器名称的方法有多种:

  1.1 调用IP helper API取得适配器名称

ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);
IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];
if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_BUFFER_OVERFLOW ) // 缓冲区不够大
{
delete pAdapterInfo;
pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];
pAdapterInfoBkp = pAdapterInfo;
}
if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_SUCCESS )
{
do{ // 遍历所有适配器
if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) // 判断是否为以太网接口
{
// pAdapterInfo->Description 是适配器描述
// pAdapterInfo->AdapterName 是适配器名称
}
pAdapterInfo = pAdapterInfo->Next;
}while(pAdapterInfo);
}
delete pAdapterInfoBkp;

  1.2 读取注册表取得适配器名称

  在Windows2000中可以通过遍历 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\000n\ (n是从0开始编号的数字)所有接口, 在Windows NT中可以读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards中的信息,下面以Windows2000为例:
HKEY hKey, hSubKey, hNdiIntKey;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}",
0,
KEY_READ,
&hKey) != ERROR_SUCCESS)
return FALSE;

DWORD dwIndex = 0;
DWORD dwBufSize = 256;
DWORD dwDataType;
char szSubKey[256];
unsigned char szData[256];

while(RegEnumKeyEx(hKey, dwIndex++, szSubKey, &dwBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
{
if(RegOpenKeyEx(hSubKey, "Ndi\\Interfaces", 0, KEY_READ, &hNdiIntKey) == ERROR_SUCCESS)
{
dwBufSize = 256;
if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
{
if(strcmp((char*)szData, "ethernet") == 0) // 判断是不是以太网卡
{
dwBufSize = 256;
if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
{
// szData 中便是适配器详细描述
dwBufSize = 256;
if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
{
// szData 中便是适配器名称
}
}
}
}
RegCloseKey(hNdiIntKey);
}
RegCloseKey(hSubKey);
}

dwBufSize = 256;
} /* end of while */

RegCloseKey(hKey);

  2、将IP信息写入注册表

  代码如下:
BOOL RegSetIP(LPCTSTR lpszAdapterName, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate)
{
HKEY hKey;
string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
strKeyName += lpszAdapterName;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
strKeyName.c_str(),
0,
KEY_WRITE,
&hKey) != ERROR_SUCCESS)
return FALSE;

char mszIPAddress[100];
char mszNetMask[100];
char mszNetGate[100];

strncpy(mszIPAddress, pIPAddress, 98);
strncpy(mszNetMask, pNetMask, 98);
strncpy(mszNetGate, pNetGate, 98);

int nIP, nMask, nGate;

nIP = strlen(mszIPAddress);
nMask = strlen(mszNetMask);
nGate = strlen(mszNetGate);

*(mszIPAddress + nIP + 1) = 0x00; // REG_MULTI_SZ数据需要在后面再加个0
nIP += 2;

*(mszNetMask + nMask + 1) = 0x00;
nMask += 2;

*(mszNetGate + nGate + 1) = 0x00;
nGate += 2;

RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAddress, nIP);
RegSetValueEx(hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNetMask, nMask);
RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)mszNetGate, nGate);

RegCloseKey(hKey);

return TRUE;
}

  3、调用DhcpNotifyConfigChange通知配置的改变

  未公开函数DhcpNotifyConfigChange位于 dhcpcsvc.dll中,原型如下:
BOOL DhcpNotifyConfigChange(
LPWSTR lpwszServerName, // 本地机器为NULL
LPWSTR lpwszAdapterName, // 适配器名称
BOOL bNewIpAddress, // TRUE表示更改IP
DWORD dwIpIndex, // 指明第几个IP地址,如果只有该接口只有一个IP地址则为0
DWORD dwIpAddress, // IP地址
DWORD dwSubNetMask, // 子网掩码
int nDhcpAction ); // 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用 DHCP

  具体调用代码如下:

BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask)
{
BOOL bResult = FALSE;
HINSTANCE hDhcpDll;
DHCPNOTIFYPROC pDhcpNotifyProc;
WCHAR wcAdapterName[256];

MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);

if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)
return FALSE;

if((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) != NULL)
if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)
bResult = TRUE;

FreeLibrary(hDhcpDll);
return bResult;
}

 二、修改注册表:网卡重启

  更改Windows网卡属性选项中IP地址, 通过对比前后注册表, 可以发现以下几处发生变化

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
\Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]
“IPAddress”
“SubnetMask”
“DefaultGateway”
“NameServer”

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip]
“IPAddress”
“SubnetMask”
“DefaultGateway”

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]
“IPAddress”
“SubnetMask”
“DefaultGateway”
“NameServer”

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip]
“IPAddress”
“SubnetMask”
“DefaultGateway”

  其中{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}是网卡名称(AdapterName), 不同的网卡, 不同的接入位置, 不同的接入的时间, 对应的值都不一样, 它的值是第一次接入系统时, 由系统生成的GUID值.

  此处CurrentControlSet实际是ControlSet001的别名.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]
“IPAddress”
“SubnetMask”
“DefaultGateway”
“NameServer”

  是主要的设置处.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip]
“IPAddress”
“SubnetMask”
“DefaultGateway”

  对一些服务有影响, 如不设置, 用netstat可以看到原来的IP地址仍处于监听状态(?).

  但为了使设置生效, 还有很重要的一步, 即重启网卡.

  更改网卡的配置, 一般而言需要重启网卡, 如Linux系统, 只需运行
  #ifconfig eth0 down
  #ifconfig eht0 up
  就可以实现网卡的重启.

  Windows环境下的步骤与之类似: 先禁用本地连接(网卡), 再启用本地连接(网卡). 但没有相应的命令或者直接的API. 所幸的是DDK提供一套设备安装函数, 用于控制系统设备, 包括控制设备的状态改变.(点击查看详细代码附件)

  总结: 通过网卡重启更改IP的方法有两个步骤: 修改注册表, 重启网卡. 重启网卡的全过程上面已作描述. 注册表修改的内容为文中列出四个主要项, 如{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}的网卡名称即是内部设备名, 在adapter结构中已给出. 整个注册表修改的过程比较简单, 本文不加叙述.

  三、使用”iphlpapi”一卡多IP

  除以上两个方法外, 笔者再介绍一种方法. 无论是在Windows下还是在Linux下, 一块网卡都可同时具有多个IP地址. 根据TCP/IP原理, 在网络层标识通信节点是IP地址, 在链路层上的则是MAC地址. 只要通过ARP, 将多个IP与一个MAC对应起来, 就可实现一网卡多IP(其实是一MAC多IP). 系统本身也有相应的设置选项, 如windows是通过TCP/IP属性的高级选项添加的, Linux下可由ifconfig命令添加.

  iphlpapi提供AddIPAddress和DelIPAddress. 如果能先加入新的IP, 再去除原来的IP, 即可实现IP地址的更改.

转自: http://www.programbbs.com/doc/3125.htm

分类: C++ 标签:

转:利用PHP操作Linux消息队列完成进程间通信

2011年11月7日 1 条评论

当我们开发的系统需要使用多进程方式运行时,进程间通信便成了至关重要的环节。消息队列(message queue)是Linux系统进程间通信的一种方式。
  关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/
  关于Linux系统消息队列的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/
  PHP的sysvmsg模块是对Linux系统支持的System V IPC中的System V消息队列函数族的封装。我们需要利用sysvmsg模块提供的函数来进进程间通信。先来看一段示例代码_1:

<?php
 
$message_queue_key = ftok(__FILE__, 'a');
 
$message_queue = msg_get_queue($message_queue_key, 0666);
var_dump($message_queue);
 
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
 
//向消息队列中写
msg_send($message_queue, 1, "Hello,World!");
 
$message_queue_status = msg_stat_queue($message_queue);
print_r($message_queue_status);
 
//从消息队列中读
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
print_r($message."\r\n");
 
msg_remove_queue($message_queue);
 
?>

这段代码的运行结果如下:

resource(4) of type (sysvmsg queue)
Array
(
    [msg_perm.uid] => 1000
    [msg_perm.gid] => 1000
    [msg_perm.mode] => 438
    [msg_stime] => 0
    [msg_rtime] => 0
    [msg_ctime] => 1279849495
    [msg_qnum] => 0
    [msg_qbytes] => 16384
    [msg_lspid] => 0
    [msg_lrpid] => 0
)
Array
(
    [msg_perm.uid] => 1000
    [msg_perm.gid] => 1000
    [msg_perm.mode] => 438
    [msg_stime] => 1279849495
    [msg_rtime] => 0
    [msg_ctime] => 1279849495
    [msg_qnum] => 1
    [msg_qbytes] => 16384
    [msg_lspid] => 2184
    [msg_lrpid] => 0
)
Hello,World!

可以看到已成功从消息队列中读取“Hello,World!”字符串
  下面列举一下示例代码中的主要函数:

ftok ( string $pathname , string $proj ) 
	手册上给出的解释是:Convert a pathname and a project identifier to a System V IPC key。这个函数返回的键值唯一对应linux系统中一个消息队列。在获得消息队列的引用之前都需要调用这个函数。
 
msg_get_queue ( int $key [, int $perms ] )
	msg_get_queue()会根据传入的键值返回一个消息队列的引用。如果linux系统中没有消息队列与键值对应,msg_get_queue()将会创建一个新的消息队列。函数的第二个参数需要传入一个int值,作为新创建的消息队列的权限值,默认为0666。这个权限值与linux命令chmod中使用的数值是同一个意思,因为在linux系统中一切皆是文件。
 
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] )
	顾名思义,该函数用来向消息队列中写数据。
 
msg_stat_queue ( resource $queue ) 
	这个函数会返回消息队列的元数据。消息队列元数据中的信息很完整,包括了消息队列中待读取的消息数、最后读写队列的进程ID等。示例代码在第8行调用该函数返回的数组中队列中待读取的消息数msg_qnum值为0。
 
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] ) 
	msg_receive用于读取消息队列中的数据。
 
msg_remove_queue ( resource $queue ) 
    msg_remove_queue用于销毁一个队列。

示例代码_1只是展示了PHP操作消息队列函数的应用。下面的代码具体描述了进程间通信的场景

<?php
 
$message_queue_key = ftok(__FILE__, 'a');
$message_queue = msg_get_queue($message_queue_key, 0666);
 
$pids = array();
for ($i = 0;  $i < 5; $i++) {
		//创建子进程
        $pids[$i] = pcntl_fork();
 
        if ($pids[$i]) {
                echo "No.$i child process was created, the pid is $pids[$i]\r\n";
        } elseif ($pids[$i] == 0) {
                $pid = posix_getpid();
                echo "process.$pid is writing now\r\n";
 
                msg_send($message_queue, 1, "this is process.$pid's data\r\n");
                posix_kill($pid, SIGTERM);
        }
}
 
do {
        msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
        echo $message;
 
        //需要判断队列是否为空,如果为空就退出
        //break;
} while(true)
 
?>

运行结果为:

No.0 child process was created, the pid is 5249
No.1 child process was created, the pid is 5250
No.2 child process was created, the pid is 5251
No.3 child process was created, the pid is 5252
No.4 child process was created, the pid is 5253
process.5251 is writing now
this is process.5251's data
process.5253 is writing now
process.5252 is writing now
process.5250 is writing now
this is process.5253's data
this is process.5252's data
this is process.5250's data
process.5249 is writing now
this is process.5249's data

这段程序每次的运行结果都会不同,这正说明了多进程的异步性。从结果也能看出消息队列FIFO特性。
以上便是我研究的一点心得。接下来将会继续研究PHP利用信号、socket等进行进程间通信的方法。

转自: http://www.cnblogs.com/TechZi/archive/2010/07/23/1783342.html

分类: PHP 标签:

转:SSL 证书入门,免费的 HTTPS(SSL) 证书颁发机构StartSSL证书使用流程攻略

2011年11月7日 没有评论

一、什么是 SSL 证书,什么是 HTTPS 网站?

SSL证书是数字证书的一种,类似于驾驶证、护照和营业执照的电子副本。SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socket layer(SSL)安全协议是由Netscape Communication公司设计开发。该安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,现已成为该领域中全球化的标准。由于SSL技术已建立到所有主要的浏览器和WEB服务器程序中,因此,仅需安装服务器证书就可以激活该功能了)。即通过它可以激活SSL协议,实现数据信息在客户端和服务器之间的加密传输,可以防止数据信息的泄露。保证了双方传递信息的安全性,而且用户可以通过服务器证书验证他所访问的网站是否是真实可靠。

二、SSL 证书分类?

从使用者角度来讲,SSL证书分为四类
Class1(Domain Validation):只验证域名所有权.
Class2(Personal Validation):验证域名所有权之外还验证个人真实身份.
Class3(Organization Validation):验证经营者身份,也就是企业验证。
EV(扩展验证):除了经营者身份之外的其他一些企业资料验证。
对于大型电子商务企业,一般都会使用Class3 EV级的证书,这样可以确保使用者的身份,取得用户信任。

对我们普通的网站来说,我们只需要Class1的证书即可。
当然你也可以自己给自己颁发一个SSL证书,但是你自己颁发的证书是不受浏览器支持的,每次访问都会有安全提示,因为你不是受信任的跟证书颁发机构,从目前的受信任根证书颁发机构里面看来,只有StartSSL一家提供免费的SSL证书,当然只限Class1,其他级别都是要花钱的了,不过没关系,我们只需要Class1即可

打开https://www.startssl.com
注册一个新用户https://www.startssl.com/?app=11&action=regform
注册之后登录邮箱即可激活帐户
注意:startssl不是使用用户名密码的方式来验证用户身份的,而是给你颁发一个独立的证书来验证你的身份,请保管好你的证书。

下面开始申请证书

登录StartSSL,点“Validations Wizard”,选择 “Domain Name Validation”,输入你的域名,选择后缀,Continue,会提示你通过哪个邮箱地址验证域名所有人,一般会有
postmaster@im286.com
hostmaster@im286.com
webmaster@im286.com
×××@××.com(域名联系信息里面的邮箱)
点击继续,收取邮件输入验证码,即可完成域名的验证,注意,域名的验证有效期为一个月,一个月之后你想再申请证书的话还要验证一次的。

验证域名之后,点Certificates Wizard,选择”Web Server SSL/TLS Certificates”,下一步,输入private key的密码(最少10位最多32位,只允许数字和字母,如果你自己有生产csr文件,则跳过这一步),下一步
把生成的PRIVATE KEY复制到记事本里面保存,注意不要做任何修改,再下一步,提示你选择域名,也就是刚才你验证过的域名,下一步填写二级域名,下一步,确定。

慢慢等待他们签发吧,等待期间最好把你的PRIVATE KEY解密一下,因为这个PRIVATE KEY是加密了的,如果直接使用这个KEY,启动Web Server的时候你需要输入PRIVATE KEY的密码才行。
点”Tool Box” , 选择”Decrypt Private Key”,输入你的Private Key和密码,好了,把解密之后的key保存为 ssl.key吧。

Nginx的SSL配置:
server
{
server_name www.im286.com;
listen 443;
index index.html index.htm index.php;
root /data/im286.com;

ssl on;
ssl_certificate ssl.cer; ##签发给你的证书
ssl_certificate_key ssl.key; ##你的Private Key
}

来源 http://www.im286.com/viewthread.php?tid=6764216

分类: Domain Name 标签: