在Windows驱动sys程序用c++写一段socket通信代码 ,需要驱动端做客户端,应用程序做服务端
时间: 2024-02-16 18:03:59 浏览: 211
用C++进行Socket编程
在 Windows 驱动程序中使用 Socket 进行通信比较麻烦,需要使用 WSK(Windows Sockets Kernel)API。以下是一个简单的示例代码:
```cpp
#include <ntddk.h>
#include <wsk.h>
PWSK_SOCKET g_pSocket = nullptr;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
UNREFERENCED_PARAMETER(pDriverObject);
UNREFERENCED_PARAMETER(pRegistryPath);
NTSTATUS status = STATUS_SUCCESS;
WSK_CLIENT_NPI wskClientNPI;
WSK_REGISTRATION wskRegistration;
WSK_PROVIDER_NPI wskProviderNPI;
PWSK_PROVIDER_LIST pProviderList = nullptr;
PWSK_SOCKET pSocket = nullptr;
SOCKADDR_IN serverAddr;
// 初始化 WSK 客户端 NPI
RtlZeroMemory(&wskClientNPI, sizeof(WSK_CLIENT_NPI));
wskClientNPI.ClientContext = nullptr;
wskClientNPI.Dispatch = WskSampleSocketDispatch;
wskClientNPI.Version = WSK_INTERFACE_VERSION_1_0;
// 注册 WSK 客户端
status = WskRegister(&wskClientNPI, &wskRegistration);
if (!NT_SUCCESS(status)) {
return status;
}
// 获取 WSK 提供程序 NPI
RtlZeroMemory(&wskProviderNPI, sizeof(WSK_PROVIDER_NPI));
status = wskRegistration.Dispatch->WskGetProviderByName(L"MSAFD Tcpip", &wskProviderNPI);
if (!NT_SUCCESS(status)) {
WskDeregister(&wskRegistration);
return status;
}
// 创建 Socket 对象
status = wskProviderNPI.Dispatch->WskSocket(wskProviderNPI.Client, AF_INET, SOCK_STREAM, IPPROTO_TCP, WSK_FLAG_BASIC_SOCKET, nullptr, nullptr, nullptr, nullptr, &pSocket);
if (!NT_SUCCESS(status)) {
wskProviderNPI.Dispatch->WskReleaseProvider(wskProviderNPI.Client);
WskDeregister(&wskRegistration);
return status;
}
// 连接到服务器
RtlZeroMemory(&serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(8888);
status = wskProviderNPI.Dispatch->WskConnect(pSocket, (PSOCKADDR)&serverAddr, 0, nullptr, nullptr, nullptr, nullptr);
if (!NT_SUCCESS(status)) {
wskProviderNPI.Dispatch->WskCloseSocket(pSocket, nullptr, nullptr);
wskProviderNPI.Dispatch->WskReleaseProvider(wskProviderNPI.Client);
WskDeregister(&wskRegistration);
return status;
}
// 发送数据
CHAR buffer[] = "Hello, world!";
ULONG bufferLength = sizeof(buffer);
status = wskProviderNPI.Dispatch->WskSend(pSocket, buffer, 0, &bufferLength, nullptr, nullptr, nullptr);
if (!NT_SUCCESS(status)) {
wskProviderNPI.Dispatch->WskCloseSocket(pSocket, nullptr, nullptr);
wskProviderNPI.Dispatch->WskReleaseProvider(wskProviderNPI.Client);
WskDeregister(&wskRegistration);
return status;
}
// 接收数据
RtlZeroMemory(buffer, sizeof(buffer));
bufferLength = sizeof(buffer);
status = wskProviderNPI.Dispatch->WskReceive(pSocket, buffer, 0, &bufferLength, nullptr, nullptr, nullptr);
if (!NT_SUCCESS(status)) {
wskProviderNPI.Dispatch->WskCloseSocket(pSocket, nullptr, nullptr);
wskProviderNPI.Dispatch->WskReleaseProvider(wskProviderNPI.Client);
WskDeregister(&wskRegistration);
return status;
}
// 关闭 Socket 对象
wskProviderNPI.Dispatch->WskCloseSocket(pSocket, nullptr, nullptr);
// 释放资源
wskProviderNPI.Dispatch->WskReleaseProvider(wskProviderNPI.Client);
WskDeregister(&wskRegistration);
return status;
}
VOID WskSampleSocketDispatch(PVOID pContext, PWSK_SOCKET pSocket, UCHAR SocketOperation, PVOID pArg1, PVOID pArg2, PVOID pArg3, PVOID pArg4)
{
UNREFERENCED_PARAMETER(pContext);
UNREFERENCED_PARAMETER(pSocket);
UNREFERENCED_PARAMETER(SocketOperation);
UNREFERENCED_PARAMETER(pArg1);
UNREFERENCED_PARAMETER(pArg2);
UNREFERENCED_PARAMETER(pArg3);
UNREFERENCED_PARAMETER(pArg4);
// TODO: 处理 Socket 事件
}
```
在上面的示例代码中,首先初始化 WSK 客户端 NPI,并注册 WSK 客户端。接着获取 WSK 提供程序 NPI,并创建 Socket 对象。然后连接到服务器,并发送和接收数据。最后关闭 Socket 对象并释放资源。
需要注意的是,上面的示例代码只是一个简单的示例,实际上使用 WSK 进行 Socket 通信比较复杂,需要处理并发、错误处理、协议解析等问题。
阅读全文