在上一篇中说了在Windows mobile下IR端口的编程使用可以通过两种方式来进行:原始方式和WinSock方式。上一篇中简单介绍了一下原始方式,在本篇中着重说明WinSock方式(IrSock)。
WinSock方式(IrSock):
Windows mobile中IrSock的通讯建立基于IrDA协议(Infrared Data Association Protocols)实现,虽然IrSock与我们经常使用的网络方式的sockets在一些函数上,使用步骤上有所差异,但是通常我们还是可以将IrSock当成普通的网络sockets来使用。
网络sockets和IrSock在使用方式差异的最主要的一点就是sockets的访问服务器地址是确定的,静止的,而IrSock访问的地址是不确定,变化的。IrSock客户端访问的时候需要对当前距离范围的逻辑地址访问点进行搜索枚举(Logical Service Access Point Selectors (LSAP-SELs))。逻辑地址访问点的范围为1-127,也就是说我们要连接到的服务器(信息访问服务(Information Access Service (IAS) ))是动态选择的(LSAP-SELs))。
服务器建立一个信息访问服务(IAS),客户通过搜索枚举逻辑地址访问点信息(LSAP-SELs)来访问服务(IAS),然后建立连接。
一,下面是IrSock的服务器建立的方法步骤,还有一段从Windows Mobile 6 SDK 帮助中获取的示例代码:
.步骤:
1,以流式数据报方式创建一个socket,使用AF_IRDA为地址格式参数,SOCK_STREAM为类型参数,NULL为协议参数;
2,使用bind建立服务器,使用SOCKADDR_IRDA结构作为地址参数;
3,使用listen侦听客户连接;
4,使用accept接受客户连接;
5,使用send 和recv收发数据;
6,使用closesocket关闭服务。
.示例:
#include <windows.h>
#include <af_irda.h>
int WINAPI WinMain (
HINSTANCE hInstance, // Handle to the current instance
HINSTANCE hPrevInstance,// Handle to the previous instance
LPTSTR lpCmdLine, // Pointer to the command line
int nCmdShow) // Show state of the window
{
SOCKET ServerSock, // IR socket bound to the server
ClientSock; // IR socket bound to the client
SOCKADDR_IRDA address = {AF_IRDA, 0, 0, 0, 0, "IRServer"};
// Specifies the server socket address
int index = 0, // Integer index
iReturn; // Return value of recv function
char szServerA[100]; // ASCII string
TCHAR szServerW[100]; // Unicode string
TCHAR szError[100]; // Error message string
// Create a socket bound to the server.
if ((ServerSock = socket (AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Allocating socket failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
return FALSE;
}
// Associate the server socket address with the server socket.
if (bind (ServerSock, (struct sockaddr *)&address, sizeof (address))
== SOCKET_ERROR)
{
wsprintf (szError, TEXT("Binding socket failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (ServerSock);
return FALSE;
}
// Establish a socket to listen for incoming connections.
if (listen (ServerSock, 5) == SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Listening to the client failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (ServerSock);
return FALSE;
}
// Accept a connection on the socket.
if ((ClientSock = accept (ServerSock, 0, 0)) == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Accepting connection with client failed.")
TEXT(" Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (ServerSock);
return FALSE;
}
// Stop listening for connections from clients.
closesocket (ServerSock);
// Send a string from the server socket to the client socket.
if (send (ClientSock, "To Client!", strlen ("To Client!") + 1, 0)
== SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Sending data to the client failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
}
// Receive data from the client.
iReturn = recv (ClientSock, szServerA, sizeof (szServerA), 0);
// Check if there is any data received. If there is, display it.
if (iReturn == SOCKET_ERROR)
{
wsprintf (szError, TEXT("No data is received, recv failed.")
TEXT(" Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Server"), MB_OK);
}
else if (iReturn == 0)
{
MessageBox (NULL, TEXT("Finished receiving data"), TEXT("Server"),
MB_OK);
}
else
{
// Convert the ASCII string to a Unicode string
szServerA[99] = 0;
MultiByteToWideChar(CP_ACP, 0, szServerA, -1,
szServerW, sizeof(szServerW)/sizeof(szServerW[0]));
// Display the string received from the client.
MessageBox (NULL, szServerW, TEXT("Received From Client"), MB_OK);
}
// Close the client and server sockets.
closesocket (ClientSock);
return 0;
}
二,下面是IrSock的客户端连接的方法步骤,还有一段从Windows Mobile 6 SDK 帮助中获取的示例代码:
.步骤:
1,以流式数据报方式创建一个socket,使用AF_IRDA为地址格式参数,SOCK_STREAM为类型参数,NULL为协议参数;
2,使用getsockopt搜索当前范围内的IR设备(服务);
3,使用connect连接到服务,其服务器地址参数为SOCKADDR_IRDA结构定义,来源于第二步返回的服务地址信息;
4,连接后使用send 和recv收发数据;
5,使用closesocket关闭服务。
.示例:
#include <windows.h>
#include <af_irda.h>
#define NUMRETYR 5 // Maximum number of retries
int WINAPI WinMain (
HINSTANCE hInstance, // Handle to the current instance
HINSTANCE hPrevInstance,// Handle to the previous instance
LPTSTR lpCmdLine, // Pointer to the command line
int nCmdShow) // Show window state.
{
SOCKET sock; // Socket bound to the server
DEVICELIST devList; // Device list
SOCKADDR_IRDA address = {AF_IRDA, 0, 0, 0, 0, "IRServer"};
// Specifies the server socket address
int iCount = 0, // Number of retries
index = 0, // Integer index
iReturn, // Return value of recv function
iDevListLen = sizeof (devList);
// Size of the device list
char szClientA[100]; // ASCII string
TCHAR szClientW[100]; // Unicode string
TCHAR szError[100]; // Error message string
// Create a socket that is bound to the server.
if ((sock = socket (AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Allocating socket failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
return FALSE;
}
// Initialize the number of devices to zero.
devList.numDevice = 0;
while ( (devList.numDevice == 0) && (iCount <= NUMRETYR))
{
// Retrieve the socket option.
if (getsockopt (sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *)&devList, &iDevListLen) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("Server could not be located, getsockopt")
TEXT(" failed. Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (sock);
return FALSE;
}
iCount++;
// Wait one second before retrying.
Sleep (1000);
}
if (iCount > NUMRETYR)
{
MessageBox (NULL, TEXT ("Server could not be located!"),
TEXT ("Error"), MB_OK);
closesocket (sock);
return FALSE;
}
// Get the server socket address.
for (index = 0; index <= 3; index++)
{
address.irdaDeviceID[index] = devList.Device[0].irdaDeviceID[index];
}
// Establish a connection to the socket.
if (connect (sock, (struct sockaddr *)&address,
sizeof (SOCKADDR_IRDA)) == SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Connecting to the server failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
closesocket (sock);
return FALSE;
}
// Send a string from the client socket to the server socket.
if (send (sock, "To Server.", strlen ("To Server.") + 1, 0)
== SOCKET_ERROR)
{
wsprintf (szError,
TEXT("Sending data to the server failed. Error: %d"),
WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Error"), MB_OK);
}
// Receive data from the server socket.
iReturn = recv (sock, szClientA, sizeof (szClientA), 0);
// Check if there is any data received. If there is, display it.
if (iReturn == SOCKET_ERROR)
{
wsprintf (szError, TEXT("No data is received, recv failed.")
TEXT(" Error: %d"), WSAGetLastError ());
MessageBox (NULL, szError, TEXT("Client"), MB_OK);
}
else if (iReturn == 0)
{
MessageBox (NULL, TEXT("Finished receiving data"), TEXT("Client"),
MB_OK);
}
else
{
// Convert the ASCII string to a Unicode string
szServerA[99] = 0;
MultiByteToWideChar(CP_ACP, 0, szServerA, -1,
szServerW, sizeof(szServerW)/sizeof(szServerW[0]));
// Display the string received from the server.
MessageBox (NULL, szClientW, TEXT("Received From Server"), MB_OK);
}
// Close the socket.
closesocket (sock);
return 0;
}
最后要说的一点,在PC上使用红外端口IrSock也是以上步骤。别忘了头文件啊!