对于任何优秀的套接字程序员:
是否可以使用套接字通过 USB 端口枚举连接到 PC 的多个活动 IrDA 设备?
如果是这样,怎么做?这真的是我的主要问题。帖子的其余部分完善了细节并描述了我尝试过的内容。
我正在使用 Microsoft SDK 和 ANSI C 编译器在 Windows 7 上开发应用程序。应用程序设计要求它检测范围内的任何 IrDA 设备,使用套接字连接,并通过多个 IrDA 加密狗(每个设备一个加密狗)与多个设备通信,每个加密狗通过 USB 连接到 PC。注意:应避免使用虚拟 COM 端口。
我已成功使用套接字调用来枚举、创建套接字、连接并与单个 IrDA 设备通信。这很好用。
但是,我不确定如何设置代码以成功枚举多个 IrDA 设备。
到目前为止,我一次只能连接到一台设备。尽管很明显,Windows 正在“发现”三个 IrDA 加密狗,如下图所示 - 整体场景(第 1 图像)、设备管理器(第 2 图像)、设备属性(第 3 图像):
图 1:总体情况:
图 2:从设备管理器:
图 3:每个“找到”的 IrDA 设备的属性
(包括后两个箭头以显示所有三个设备的 Port-Hub 地址)
我正在使用的简单场景:(
一些变量名称与上面的场景描述不同,但在代码中是一致的)
第一个- 我将两个有源 IrDA 设备放在两个加密狗前面(相隔几英尺,因此两个设备之间没有信号模糊)现在只使用 2 个来保持简单。
第二- 我创建 2 个 IrDA 套接字,使用以下方法获取两个句柄: socket(AF_IRDA, SOCK_STREAM, 0);
第三- 我打电话:
if ((errorCode = getsockopt(gSocketHandle[0],
SOL_IRLMP,
IRLMP_ENUMDEVICES,
(char*)pDeviceList,
&deviceListLength)) == SOCKET_ERROR)
4th - 然后我用 pDeviceList 中的新信息填充 destinIrdaDeviceAddr 和
memcpy(&destinIrdaDeviceAddr.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);
5 - 调用:
connect(gSocketHandle[0],(const struct sockaddr*)&destinIrdaDeviceAddr,(int) sizeof(SOCKADDR_IRDA))
此调用完成后,我使用下一个套接字句柄(gSocketHandle 1 )重复(步骤 3 )。但是,我没有得到另一个枚举设备,而是得到了相同的设备。第二次调用会在 pDeviceList 中产生与第一个设备中相同的信息。换句话说,我只列举了一个设备。
下面是尝试枚举两个 IrDA 设备的代码:
// adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/ms691754(v=vs.85).aspx
#include <windows.h>
#include <winsock2.h>
#include <ansi_c.h>
#include <af_irda.h>
#pragma comment(lib, "ws2_32.lib")
#define DEVICE_LIST_LEN 5
#define MAX_RETRIES 10
SOCKET conn1, conn2;
char* iGetLastErrorText(DWORD nErrorCode);
void main()
{
WSADATA wsaData;
// discovery buffer
BYTE DevListBuff[sizeof(DEVICELIST) - sizeof(IRDA_DEVICE_INFO) +
(sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof(DevListBuff);
PDEVICELIST pDevList = (PDEVICELIST) &DevListBuff;
int DevNum, i;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
printf("IR-Client: Unable to load the Winsock library!\n");
getchar();
}
else printf("IR-Client: Winsock library 2.2 loaded!\n");
SOCKADDR_IRDA DstAddrIR = { AF_IRDA, 0, 0, 0, 0, "IrDA:IrCOMM" };
//Create socket handles
if ((conn1 = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
// WSAGetLastError
}
if ((conn2 = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
// WSAGetLastError
}
/////////////////////////
//enumerate devices - socket conn1
/////////////////////////
// search for the peer device
pDevList->numDevice = 0;
if (getsockopt(conn1, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen)
== SOCKET_ERROR)
{
// WSAGetLastError
}
if (pDevList->numDevice == 0)
{
printf("no devices found\n");
}
// assume first device, we should have a common dialog here
memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);
printf("%x\n", &DstAddrIR.irdaDeviceID[0]);
// nothing special for IrCOMM from now on...
if (connect(conn1, (const struct sockaddr *) &DstAddrIR, sizeof(SOCKADDR_IRDA))
== SOCKET_ERROR)
{
// WSAGetLastError
}
/////////////////////////
//enumerate devices - socket conn2
/////////////////////////
// search for the peer device
pDevList->numDevice = 0;
if (getsockopt(conn2, SOL_IRLMP, IRLMP_ENUMDEVICES, (CHAR *) pDevList, &DevListLen) == SOCKET_ERROR)
{
// WSAGetLastError
}
if (pDevList->numDevice == 0)
{
printf("no devices found\n");
}
// assume first device, we should have a common dialog here
memcpy(&DstAddrIR.irdaDeviceID[0], &pDevList->Device[0].irdaDeviceID[0], 4);
printf("%x\n", &DstAddrIR.irdaDeviceID[0]);
// nothing special for IrCOMM from now on...
if (connect(conn2, (const struct sockaddr *) &DstAddrIR, sizeof(SOCKADDR_IRDA))
== SOCKET_ERROR)
{
// WSAGetLastError
}
getchar(); //to view irdaDeviceID
}
char* iGetLastErrorText(DWORD nErrorCode)
{
char* msg;
// Ask Windows to prepare a standard message for a GetLastError() code:
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, nErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
// Return the message
if (!msg)
return("Unknown error");
else
return(msg);
}
下图显示了 ->irdaDeviceID[0] 的值。两个值相同,表示仅枚举了一个设备。