11.1.1 Select I/O模型

在Windows CE中,Select模型是唯一被支持的I/O模型。Select I/O模型就是利用select函数对I/O进行管理。

函数select的功能在于获取一个或多个套接字的状态,以及在必要的时候执行同步I/O操作进行等待。它的原型如下:

int select(

int nfds,

fd_set FAR* readfds,

fd_set FAR* writefds,

fd_set FAR* exceptfds,

const struct timeval FAR* timeout

);

参数nfds被忽略,只是为了保持与Berkeley的套接字规范相兼容。

参数readfds指向用于检查可读性的一系列套接字。

参数writefds指向用于检查可写性的一系列套接字。

参数exceptfds指向用于检查错误的一系列套接字。

参数timeout设置select函数能够最多等待的I/O操作时间。在阻塞操作时,该参数被设置为NULL,表示必须有操作发生才停止等待。

该函数返回结构体fd_set结构体中处于准备好状态的套接字句柄的数目。如果超时,函数select返回0;否则,在发生错误的时候返回SOCKET_ERROR。函数WSAGetLastError能返回的错误码以及相应的描述如下:如表11-14

错误码

描述

WSANOTINITIALISED

必须在成功调用WSAStartup函数之后,才能调用此函数

WSAENETDOWN

网络子系统出错或者相关的服务提供者出现故障

WSAEINPROGRESS

阻塞性的Winsock函数正在被调用,或是服务提供者正在处理回调函数

WSAENOTSOCK

指定的套接字描述符不是合法的套接字

WSAEFAULT

参数argp不是合法的用户地址空间的地址

WSAEINVAL

参数不被支持或是不合法

WSAEINTR

套接字被关闭

表11-14错误码以及对应描述

该函数用于获取一个或多个套接字的状态。对于每个套接字来说,函数能够分别获取读、写以及发生错误的状态。待查询状态的套接字用结构体fd_set来表示。统一个fd_set结构体中的所有套接字必须和同一个服务提供者相关联。函数返回的时候,结构体fd_set的值反映了满足指定条件的套接字。而函数返回值代表了满足指定条件的套接字的数目。

如果套接字处于监听的状态且有连接请求到达,那么fd_set中相应的位被设置为可读,而accept函数不被阻塞而直接完成。对于其他状态的套接字来说,可读性表示队列中存在数据,而接收函数,如recv和recvfrom不用被阻塞。

如果套接字在处理非阻塞的connect函数调用,套接字只有在创建连接成功完成的时候才被设置为可写。如果套接字不是处理connect函数调用,可写行表示发送函数,如send和sendto,能够保证成功执行。

在readfds、writefds和exceptfds这三个参数中,最多只能有两个参数被同时设置为空;而另外的非空参数中至少包含一个套接字的句柄。

readfds集合包括符合下述任一条件的套接字:

1) 如果listen函数已经被调用,而且一个连接正在被建立,那么accept函数将成功执行。

2) 有供读取的数据;如果SO_OOBINLINE属性被设置,这里的数据包括带外数据。

3) 连接被关闭、重置或是中断。

writefds集合包括符合下述任一条件的套接字:

1) 如果正在处理一个非阻塞的connect函数调用,那么连接会成功。

2) 数据能够被发送。

exceptfds集合包括符合下述任一条件的套接字:

1) 如果正在处理一个非阻塞的connect函数调用,连接尝试会失败。

2) 在SO_OOBINLINE属性被禁止的情形下,有带外数据可以被读取。

Winsock动态链接库还提供了相应的fd_set结构体的函数,便于程序对fd_set的控制。主要的fd_set结构体操作函数如下:

1) FD_CLR(s, *set):从集合set中删除套接字s。

2) FD_ISSET(s, *set):检查套接字s是否是集合set的一员。如果是,返回非零值;否则,返回0。

3) FD_SET(s, *set):往集合set中添加套接字s。

4) FD_ZERO(*set):初始化集合set为空集合。

11.1 Ping编程

11.2.1 Ping编程概述

在Windows环境中,Ping命令是常见的网络命令。它的主要目的是探测目标机器是否可达,以及检测两者间的网络状态;而它的实现主要是通过向目标机器发送一个ICMP(Internet Control Message Protocol)格式的包来完成的。

ICMP协议是一个在网络主机间执行流控制、错误信息、路由或是其他数据的网络协议。它主要用于网络Ping(或是Packet Internet Groper)中。

在RFC 792的网络协议规范中,ICMP定位于维护状态的协议,且作为IP协议的一部分,工作在ISO模型的网络层中。ICMP的消息都封装成IP数据包的格式,因而可以在网络中进行路由传输。在Windows CE中,ICMP的用途主要有:

1) 创建和维护路由表;

2) 路由发现;

3) 错误诊断;

4) 路由选择;

5) 流量控制。

要编写Ping的应用程序,离不开三个Winsock API函数的支持:IcmpCreateFile, IcmpSendEcho和IcmpSendEcho。

一、函数IcmpCreateFile介绍

函数IcmpCreateFile的功能在于创建一个用于发送ICMP请iude句柄,原型如下:

HANDLE WINAPI IcmpCreateFile (VOID);

函数执行成功时,返回有效的ICMP句柄;否则,返回INVALID_HANDLE_VALUE。

二、函数IcmpSendEcho介绍

函数IcmpSendEcho的功能在于发送一个Ping数据包,即ICMP协议包,并接受一个或多个应答。它的原型如下:

DWORD WINAPI IcmpSendEcho(

HANDLE IcmpHandle,

IPAddr DestinationAddress,

LPVOID RequestData,

WORD RequestSize,

PIP_OPTION_INFORMATION RequestOptions,

LPVOID ReplyBuffer,

DWORD ReplySize,

DWORD Timeout );

参数IcmpHandle指定了ICMP的句柄,这个句柄是由函数IcmpCreateFile打开的。

参数DestinationAddress指定了目标主机的IP地址。

参数RequestData指定了要发送数据包的缓存。

参数RequestSize指定了要发送数据包的长度,及参数RequestData中数据的长度。

参数RequestOptions指定了请求IP头的方式,可以为空。另外,还支持的方式有时间戳(IP_OPT_TS)和记录路由(IP_OPT_RR)。

参数ReplyBuffer表示应答数据的缓存。在函数返回的时候,这个缓存会保存一个或多个ICMP_ECHO_REPLY结构体,以及相应的选项和数据。

参数ReplySize表示收到的应答数据的大小。

参数Timeout表示指定等待应答的最大时间,单位是毫秒。

函数执行成功的时候,返回收到的应答的数目;否则,返回0。

三、函数IcmpCloseHandle介绍

函数IcmpCloseHandle的功能在于关闭ICMP句柄,原型如下:

BOOL WINAPI IcmpCloseHandle(

HANDLE IcmpHandle );

参数IcmpHandle是已经被函数IcmpCreateFile打开的ICMP句柄。

函数执行成功,返回TRUE;否则,返回FALSE。

如果在程序中需要探测目标主机是否可达,程序的执行流程如下:

1. 调用IcmpCreateFile函数创建一个新的ICMP句柄。

2. 循环调用IcmpSendEcho函数发送ICMP数据包并接收应答。在网络不可达,或是连接超时,函数会返回错误。

3. 调用IcmpCloseHandle函数关闭已经创建的ICMP句柄。

11.2.2 Ping编程示例

11.2 RAS拨号编程

RAS,即远程访问服务(Remote Access Service),主要连接远程主机和本地计算机。它允许用户将远程节点的计算机连接到一个本地计算机网络。如果建立了连接,就可以像访问局域网中的计算机一样,即使计算机实际连接的是一个远程网络。

在Windows CE 的 RAS 架构中, RAS 直接与 PPP 协议( Point-to-Point 协议)通信,创建连接到远程访问的通路。 RAS 利用 PPP 协议将需要进行传输的数据封装成 IP 数据包,并通过点对点的链路将数据发送出去。当 PPP 协议接收到从 TCP/IP 协议上发送过来的 IP 请求数据包时,它将包发送到 AsyncMAC 微端口。之后, AsyncMAC 将数据包组装成异步帧,并调用 Win32 的串行 API 将包转发到 TAPI 设备。这样,就完成了数据包的传输。整个数据包的处理和控制流程如图 11.2 所示。

下面将介绍Windows CE为RAS架构提供的一些常用的API。

11.3.1 建立拨号连接

在Winsock为RAS架构提供的服务中,函数RasDial用于建立拨号连接。函数RasDial的功能在于在RAS客户端和RAS服务器端,即本地主机和远程主机间建立一个RAS连接。这个连接中传输的数据包括了相互间的反馈信息,以及用户的认证信息。函数RasDial的原型如下:

DWORD RasDial(

LPRASDIALEXTENSIONS dialExtensions,

LPTSTR phoneBookPath,

LPRASDIALPARAMS rasDialParam,

DWORD NotifierType,

LPVOID notifier,

LPHRASCONN pRasConn

);

参数dialExtensions将被忽略,应该被设置为空。在Windows CE中,它的默认值为RASDIALEXTENSIONS。

参数phoneBookPath的值也应该被设置为空。在拨号连接中,拨号名都存储在注册表的电话本表项中,而不是电话本文件中。

参数rasDialParam是指向结构体RASDIALPARAMS的指针,指定了拨号和用户身份验证参数。结构体RASDIALPARAMS的定义如下:

typedef struct _RASDIALPARAMS {

DWORD dwSize;

TCHAR szEntryName[ RAS_MaxEntryName + 1 ];

TCHAR szPhoneNumber[ RAS_MaxPhoneNumber + 1 ];

TCHAR szCallbackNumber[ RAS_MaxCallbackNumber + 1 ];

TCHAR szUserName[ UNLEN + 1 ];

TCHAR szPassword[ PWLEN + 1 ];

TCHAR szDomain[ DNLEN + 1 ];

} RASDIALPARAMS;

结构体RASDIALPARAMS的属性如下:

1) dwSize域指定了结构体的大小,单位为字节数。

2) szEntryName域指定了建立拨号连接的名称,不能为空。

3) szPhoneNumber域被忽略,应该设置为空。

4) szCallbackNumber域被忽略,应该设置为空。

5) szUserName域指定了连接用户的用户名。它是RAS服务器进行身份验证的用户名,不能为空。

6) szPassword域指定了连接用户的密码。它是RAS服务器进行身份验证的用户名的密码,不能为空。

7) szDomain域指定了连接用户所在的域。

参数NotifierType指定了参数notifier的属性。如果参数notifier为空,那么参数NotifierType被忽略;否则,参数NotifierTye的值为0xFFFFFFFF。

参数notifier指向了接收建立连接过程消息的窗口句柄。如果参数notifier不为空,那么RasDial将会每一个RasDial建立连接的事件发送一个消息。此时,RasDial执行异步调用。这表示RasDial在进行连接的同时,函数调用会立即返回。如果参数notifier为空,RasDial执行同步调用。这表示知道RasDial连接完成后,不论成功或失败,才会返回。

参数pRasConn指定RasDial函数建立的拨号连接句柄。

下面的程序展示如何使用RasDial函数来进行异步调用。

BOOL MakeRasDial (HWND hDlgWnd)

{

BOOL bPassword;

TCHAR szBuffer[100];

if (bUseCurrent)

{

// Get the last configuration parameters used for this connection.

// If the password was saved, then the logon dialog box will not be

// displayed.

if (RasGetEntryDialParams (NULL, &RasDialParams, &bPassword) != 0)

{

MessageBox (hDlgWnd,

TEXT("Could not get parameter details"),

szTitle,

MB_OK);

return FALSE;

}

}

else

{

// Display the Authentication dialog box.

DialogBox (hInst, MAKEINTRESOURCE(IDD_AUTHDLG), hDlgWnd,

AuthDlgProc);

// Set hRasConn to NULL before attempting to connect.

hRasConn = NULL;

// Initialize the structure.

memset (&RasDialParams, 0, sizeof (RASDIALPARAMS));

// Configure the RASDIALPARAMS structure.

RasDialParams.dwSize = sizeof (RASDIALPARAMS);

RasDialParams.szPhoneNumber[0] = TEXT('\0');

RasDialParams.szCallbackNumber[0] = TEXT('\0');

wcscpy (RasDialParams.szEntryName, szRasEntryName);

wcscpy (RasDialParams.szUserName, szUserName); //This is optional

wcscpy (RasDialParams.szPassword, szPassword); //This is optional

wcscpy (RasDialParams.szDomain, szDomain); //This is optional

}

// Try to establish RAS connection.

if (RasDial (NULL,            // Extension not supported

NULL,            // Phone book is in registry

&RasDialParams,  // RAS configuration for connection

0xFFFFFFFF,      // Notifier type is a window handle

hDlgWnd,         // Window receives notification message

&hRasConn) != 0) // Connection handle

{

MessageBox (hDlgWnd,

TEXT("Could not connect using RAS"),

szTitle,

MB_OK);

return FALSE;

}

wsprintf (szBuffer, TEXT("Dialing %s..."), szRasEntryName);

// Set the Dialing dialog box window name to szBuffer.

SetWindowText (hDlgWnd, szBuffer);

return TRUE;

}

11.3.2 关闭拨号连接

函数RasHangUp是Winsock中用于关闭拨号连接的函数,原型如下:

DWORD RasHangUp(

HRASCONN Session

);

参数Session是待关闭的连接的句柄。它是函数RasDial或函数RasEnumConnections返回的一个句柄。

函数执行成功的时候,返回值为0;否则,返回非零值。

在拨号连接的过程中,如果连接关闭,连接端口需要花很长时间来重新设置这个连接,因此,应该一直等到端口连接完全关闭为止。要判断连接是否完全关闭,可以调用函数RasGetConnectStatus来判断。

函数RasGetConnectStatus的功能在于获取当前RAS的状态信息,原型如下:

DWORD RasGetConnectStatus(

HRASCONN rasconn,

LPRASCONNSTATUS lprasconnstatus

);

参数rasconn是函数RasDial或RasEnumConnections返回的句柄。

参数lprasconnstatus是一个指向结构体RASCONNSTATUS的指针,用来获取当前的连接状态。结构体RASCONNSTATUS的定义如下:

typedef struct _RASCONNSTATUS {

DWORD dwSize;

RASCONNSTATE rasconnstate;

DWORD dwError;

TCHAR szDeviceType[ RAS_MaxDeviceType + 1 ];

TCHAR szDeviceName[ RAS_MaxDeviceName + 1 ];

} RASCONNSTATUS;

结构体RASCONNSTATUS的属性如下:

1) dwSize域指定了结构体的大小,单位为字节数。

2) rasconnstate域指定了当前RasDail连接的状态。它可选的值是RASCS_Connected和RASCS_Disconnected,分别表示建立连接成功或是失败。

3) dwError域如果不为空,则表示失败的原因。它的可选值是:ERROR_NOT_ENOUGH_MEMORY和ERROR_INVALID_HANDLE。

4) szDeviceType域表示连接所用的设备类型,不能为空。

5) szDeviceName域表示当前的设备名,不能为空。

11.3.3 列举已建立的活动连接

函数RasEnumConnections的功能在于列举当前所有活动的拨号连接,该函数的原型如下:

DWORD RasEnumConnections(

LPRASCONN lprasconn,

LPDWORD lpcb,

LPDWORD lpcConnections

);

参数lprasconn指向结构体RASCONN的结构数组,每个数组项代表一个RAS连接。结构体RASCONN的定义如下:

typedef struct _RASCONN {

DWORD dwSize;

HRASCONN hrasconn;

TCHAR szEntryName[ RAS_MaxEntryName + 1 ];

} RASCONN;

结构体RASCONNSTATUS的属性如下:

1) dwSize域指定了结构体的大小,单位为字节数。

2) hrasconn域代表拨号连接句柄。

3) szEntryName域代表拨号连接时的名字,不能为空。

参数lpcb表示参数lprasonn的数据大小。

参数lpcConnections表示活动连接的数目。

函数RasEnumConnections的返回值为0,表示执行成功;否则,表示失败。

下面的程序展示如何关闭当前所有活动的拨号连接。

DWORD CloseRasConnections ()

{

int index;                 // An integer index

TCHAR szError[100];        // Buffer for error codes

DWORD dwError,             // Error code from a function call

dwRasConnSize,       // Size of RasConn in bytes

dwNumConnections;    // Number of connections found

RASCONN RasConn[20];       // Buffer for connection state data

// Assume the maximum number of entries is

// 20.

// Assume no more than 20 connections.

RasConn[0].dwSize = sizeof (RASCONN);

dwRasConnSize = 20 * sizeof (RASCONN);

// Find all connections.

if (dwError = RasEnumConnections (RasConn, &dwRasConnSize,

&dwNumConnections))

{

wsprintf (szError, TEXT("RasEnumConnections Error: %ld"), dwError);

return dwError;

}

// If there are no connections, return zero.

if (!dwNumConnections)

{

wsprintf (szError, TEXT("No open RAS connections"));

return 0;

}

// Terminate all of the remote access connections.

for (index = 0; index < (int)dwNumConnections; ++index)

{

if (dwError = RasHangUp (RasConn[index].hrasconn))

{

wsprintf (szError, TEXT("RasHangUp Error: %ld"), dwError);

return dwError;

}

}

return 0;

}

11.3 UDP编程概述

UDP(User Datagram Protocol),即用户数据报协议,提供无连接的、不可靠的传输服务。“无连接”意味着在相互交换数据之前,通信主机间没有建立连接链路。UDP的这种“无连接”数据传输服务无法保障数据的可靠传输。UDP既不保证数据报被正确发送出去,也不会发送确认信息。另外,UDP协议也不能保证数据报的有序性。UDP经常用于“一对多”的通信,既能够向若干个目标发送数据,也能接收发自若干个源的数据。

由于UDP数据报不保证的可靠性,应用程序必须采取机制来维护UDP传送数据的可靠性。虽然UDP不保证顺序性、可靠性和无重复性等限制,UDP协议仍用于很多场景。例如,Winsock库的IP组播技术就是利用UDP数据报来实现的。而且,UDP的传输效率高和延迟小。Microsoft的网络利用UDP处理网络登录、浏览以及域名解析。

在编程方面,UDP实现相对简单。UDP服务器不需要监听或是接收客户端的连接,而UDP客户端也不用连接到服务器。UDP服务器端和客户端的编程流程如图11.3所示。

UDP通信中服务器端的代码的执行流程如下:

1) 调用socket函数创建一个数据报套接字。其中,参数address format的值为AF_INET,而参数type的值为SOCK_DGRAM。

2) 调用bind函数。其中,参数address使用SOCKADDR_IN结构体。

3) 调用函数sendto和recvfrom与客户端进行数据的交换。

4) 调用closesocket函数关闭连接。此时,函数shutdown对于UDP套接字来说无效。

UDP通信中客户端的代码的执行流程如下:

1) 调用socket函数创建一个数据报套接字。

2) 调用函数sendto和recvfrom与服务器端进行数据的交换。

11.4 TCP编程概述

TCP(Transport Control Protocol),即传输控制协议,提供了无差错无重复且顺序的数据传输。TCP的套接字也被称为流式套接字。与UDP通信不同,应用程序在利用TCP进行通信之前,客户端和服务器端会建立一个虚拟连接,创建一个虚拟的数据传输链路。当这个连接成功建立之后,客户端和服务器端就可以把数据当作一个双向字节流进行交换。

在编程方面,TCP编程相对于UDP编程来说要复杂的多。TCP服务器端和客户端的编程流程如图11.4所示。

TCP通信中服务器端的代码的执行流程如下:

1) 调用socket函数创建一个流式套接字。其中,参数address format的值为AF_INET,而参数type的值为SOCK_STREAM。

2) 调用bind函数。其中,参数address使用SOCKADDR_IN结构体。

3) 调用listen函数监听客户端发送的连接请求。

4) 如果监听到有客户端发出连接请求,调用accept函数建立与客户端的连接;否则,一直在3)处循环等待。

5) 调用send和recv函数与客户端进行数据的交换。

6) 调用closesocket函数关闭连接。为了保证TCP连接上的数据不会丢失,可以先调用shutdown函数关闭所有的连接。

TCP通信中客户端的代码的执行流程如下:

1) 调用socket函数创建一个流式套接字。其中,参数address format的值为AF_INET,而参数type的值为SOCK_STREAM。

2) 调用connect函数向服务器发起连接请求。其中,参数address使用SOCKADDR_IN结构体。

3) 调用send和recv函数与客户端进行数据的交换。

4)

调用 closesocket 函数关闭连接。为了保证 TCP 连接上的数据不会丢失,可以先调用 shutdown 函数关闭所有的连接。

11.5 小结

本章主要介绍了Windows Embedded Compact 7中网络编程的基础,以及常见的TCP、UDP等编程的概述。首先,介绍了Windows CE中网络编程的基础,也就是套接字。对如何在Windows CE环境中使用套接字,以及常用的套接字的API作了讲解。其次,介绍了Windows CE的网络编程中最常见的四种编程方式:Ping编程、RAS拨号编程、UDP编程以及TCP编程。

Windows Embedded Compact 7网络编程概述(下)的更多相关文章

  1. Windows Embedded Compact 7网络编程概述(上)

    如今,不论是嵌入式设备.PDA还是智能手机,网络都是必不可少的模块.网络使人们更方便地共享设备上的信息和资源.而且,利用智能手机浏览互联网,也逐渐成为生活中的常见手段.物联网所倡导的物物相联,也离不开 ...

  2. Windows Embedded Compact 2013升级:VS2013也能编译

    IT之家(www.ithome.com):Windows Embedded Compact 2013升级:VS2013也能编译 今天,微软为Windows Embedded Compact 2013送 ...

  3. Windows Embedded Compact 2013 安装体验

    6月14日,微软正式发布了Windows embedded compact 2013,大家还是习惯称之为Window CE 8,公司也要开始做windows embedded compact 2013 ...

  4. Android网络编程概述

    Android网络编程概述 首先,应该了解的几个问题: 1)Android平台网络相关API接口 a) java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流.数据包 ...

  5. Windows Embedded Compact 7 开发环境搭建

    第一步,我们会定制一个运行在Vitual PC上的image.要完成这个任务,你要保证你的电脑上安装了:1.Windows Virtual PC 2.Visual Studio 2008+SP1 3. ...

  6. Windows Embedded Compact 7新特性

    Windows® Embedded Compact 7是Windows Embedded CE的下一代产品,而Windows Embedded CE这款操作系统面向占用资源少的新颖设备.Windows ...

  7. Windows Embedded Compact 7初体验

    Windows Embedded Compact 7初体验 Windows Embedded Compact 7已经出来半年多了,一直没时间搞.最近它又出了Refresh的版本,电脑也换了个1T的硬盘 ...

  8. Unix下网络编程概述

    这部分我要学习的是Unix下的网络编程,参照的书籍是W. Richard. Stevens的<Unix网络编程>卷一和卷二,由于本身现在从事的工作是java后台开发,对客户端-服务器的这种 ...

  9. JAVA学习第五十九课 — 网络编程概述

    网络模型 OSI(Open System Interconnection)开放系统互连:參考模型 TCP/IP 网络通讯要素 IP地址 port号 传输协议 网络參考模型 七层OSI模型的基本概念要了 ...

随机推荐

  1. jmeter主要组件

    1.测试计划(Test plan) 2.线程组(Thread Group) 3.配置原件(Configuration) 4.逻辑控制器(Login Controller) 5.取样器(Sampler) ...

  2. 后门技术和Linux LKM Rootkit详解

    2010-01-15 10:32 chinaitlab chinaitlab 字号:T | T 在这篇文章里, 我们将看到各种不同的后门技术,特别是 Linux的可装载内核模块(LKM). 我们将会发 ...

  3. Linux下web服务的搭建

    1.安装Apache Apache的官网地址为:http://httpd.apache.org/,这里以源码的方式进行安装,我们下载的版本是“httpd-2.4.25.tar.gz”,下载后的压缩文件 ...

  4. Linux 用户篇——用户管理的配置文件

    一.用户管理之配置文件的重要性 在Linux系统中,用户账户的相关信息是存放在相关配置文件中.而Linux安全系统的核心是用户账号,用户对系统中各种对象的访问权限取决于他们登录系统时用的账户,并且Li ...

  5. 在ubuntu下安装kaldi基本步骤

    注:最近在学习kaldi语音识别工具,在安装过程中遇到了许多问题,在此记录,以备后需. 在一开始,我看了这篇博客(http://blog.topspeedsnail.com/archives/1001 ...

  6. spirng boot打包成war部署

    最近一段时间一直在研究和学习springboot,感觉其十分便利好用.以前使用spring搭建项目都整好多繁琐的配置,使用了springboot后这些繁琐的配置统统都不要了.但就是对springboo ...

  7. JS 数组求 最大值、最小值、平均值以及求和方法

    function arrMaxNum2(arr) { return Math.max.apply(null, arr); } function arrMinNum2(arr) { return Mat ...

  8. windbg调试相关命令

    windbg 查找函数:x exe!main* 条件断点打印字符:bp 7199a2b0 ".printf \"message:%ma\", poi(@esp+8);.e ...

  9. 关于Hibernate中的临时态, 持久态, 游离态

    三态的基本概念: 1, 临时状态(Transient):也叫自由态,只存在于内存中,而在数据库中没有相应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象: ...

  10. MYSQL注入天书之开天辟地

    MYSQL注入天书 在线版本:xianzhi.aliyun.com 第一篇地址:https://xianzhi.aliyun.com/forum/read/314.html第二篇地址:https:// ...