WinSock Non-Blocking I/O
WinSock Non-Blocking I/O
本文关键字:Non-Blocking WinSock 更新时间:2023-10-16
我有一个WSASocket,当连接时调用CreateProcess和服务器cmd.exe,我想在进程hStdInput和套接字句柄之间实现一个管道来解析通过套接字发送的命令,除了当我运行像"ping 127.0.0.1"这样的命令并且必须等待输出时, 在我通过套接字发送更多数据之前,什么都没有显示,似乎我的 ReadFile 调用阻止了 hStdOut 处理程序发送任何内容。有什么办法可以解决这个问题吗?请不要被我的代码冒犯,我正在编写这个项目作为学习练习,任何帮助将不胜感激。
int syncShell(SOCKET *ConnectSocket) {
int iResult = 0;
printf("Spawning processn");
char Process[] = "C:\Windows\System32\cmd.exe";
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
sinfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
// create pipe for external commands
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE hReadPipe = NULL, hWritePipe = NULL;
iResult = CreatePipe(&hReadPipe, &hWritePipe, &saAttr, DEFAULT_BUFLEN);
if (iResult == 0) {
printf("Pipe Error");
}
sinfo.hStdOutput = sinfo.hStdError = (HANDLE) *ConnectSocket;
sinfo.hStdInput = hReadPipe;
if (!CreateProcessA(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo)) {
printf("CreateProcess failed (%d).n", GetLastError());
}
// implement pipe logic
char buf[DEFAULT_BUFLEN];
DWORD len = 0;
WSABUF DataBuf;
while (1) {
// causing the block?
iResult = ReadFile((HANDLE) *ConnectSocket, buf, DEFAULT_BUFLEN, &len, NULL);
if (iResult == 0) {
printf("File Error or non-blocking");
}
else {
printf("%d: %.*sn", len, len, buf);
WriteFile(hWritePipe, buf, len, NULL, NULL);
}
Sleep(1000);
}
WaitForSingleObject(pinfo.hProcess, INFINITE); // waits till proc finishes
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
printf("Process exitedn");
return 0;
}
首先,根据 [ReadFile
] 文档:
对于异步读取操作,hFile 可以是任何句柄 通过
CreateFile
函数用FILE_FLAG_OVERLAPPED
标志打开, 或socket
或accept
函数返回的套接字句柄。
默认情况下,socket
创建带有WSA_FLAG_OVERLAPPED
的套接字句柄。 如果传递重叠句柄并将ReadFile
的最后一个参数设置为NULL
,您将收到错误代码 87(ERROR_INVALID_PARAMETER
(。 要使用的示例重叠:
OVERLAPPED oRead = { 0 };
oRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
iResult = ReadFile((HANDLE)ConnectSocket, buf, DEFAULT_BUFLEN, &len, &oRead);
if (!iResult && GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(oRead.hEvent, INFINITE);
}
buf[oRead.InternalHigh] = 0; //set string terminator for printf
printf("%sn", buf);
WriteFile(hWritePipe1, buf, oRead.InternalHigh, NULL, NULL);
最好直接使用recv()
:
iResult = recv(ConnectSocket, buf, DEFAULT_BUFLEN, 0);
buf[iResult] = 0; //set string terminator for printf
printf("%sn", buf);
WriteFile(hWritePipe1, buf, iResult, NULL, NULL);
此外,重叠的套接字可用于将 IO 重定向到子进程 您可以创建 2 个管道来与子进程通信:
iResult = CreatePipe(&hReadPipe1, &hWritePipe1, &saAttr, DEFAULT_BUFLEN);
if (iResult == 0) {
printf("Pipe Error");
}
iResult = CreatePipe(&hReadPipe2, &hWritePipe2, &saAttr, DEFAULT_BUFLEN);
if (iResult == 0) {
printf("Pipe Error");
}
从子进程(cmd.exe
(读取并发送到客户端。
或
只需使用WSASocket
而不是socket
,并且不要指定WSA_FLAG_OVERLAPPED
。(推荐(
相关文章:
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- (Winsock) UDP 接收工作正常,但同一套接字的发送失败
- WinSock Non-Blocking I/O
- 收到错误"invalid use of non-static data member 'stu::n' "
- C++/SDL "initial value of reference to a non-const must be an lvalue"
- 使用 winsock 接收 http 请求
- 具有std::initializer_list参数的非成员函数(/non构造函数上下文)的重载解析
- C++ "Invalid use of 'this' in non-member function" ,
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- Linux non-persistent backing store for mmap()
- 如何查找 winsock.h 在 Visual Studio 中的包含位置
- std::span constructor, libcxx vs libstdc++, template vs non-
- 在Linux上交叉编译Windows应用程序时如何链接到Winsock?
- C++低吞吐量 winsock TCP 测试应用程序
- "Warning : No return statement in function returning non-void"是什么意思?
- 从Qt QJsonDocument::toBinaryData使用non-Qt读取Binary Json?
- C++线程"Call to non-static member function without an object argument"
- 出现这种错误的原因是什么"invalid use of non-static data member "
- Non blocking getch()