【问题标题】:Pipes doesn't work in WinApi on Windows 7 but works on Windows 10Pipes 在 Windows 7 上的 WinApi 中不起作用,但在 Windows 10 上起作用
【发布时间】:2017-04-26 18:07:48
【问题描述】:

我在winapi中做了一个服务器和一个客户端。

客户端发送一个数字和一个基数,服务器返回该基数的数字。 我的问题是它在 Windows 10 中有效,但在 Windows 7 中无效,我不明白为什么。有什么帮助吗?

客户:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <windows.h>
#include <string>

#define BUFFSIZE 512
using namespace std;


int main()
{
    LPDWORD bytesRead = 0;
    char res[50];
    int num, base;

    LPCTSTR Roura = TEXT("\\\\.\\pipe\\pipeline");
    HANDLE h = CreateFile(Roura, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);


    while (true) {
        for (int i = 0; i < 50; i++) {
            res[i] = 0;
        }
        printf("Number: ");
        cin >> num;
        WriteFile(h, &num, sizeof(int), NULL, NULL);
        if (num == 0) {
            CloseHandle(h);
            return 0;
        }
        printf("Base: ");
        cin >> base;
        WriteFile(h, &base, sizeof(int), NULL, NULL);
        ReadFile(h, res, BUFFSIZE, bytesRead, NULL);
        cout << res << endl;
    }

    return 0;
}

服务器:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <windows.h>
#include <string>

#define _CRT_SECURE_NO_WARNINGS
#define BUFFSIZE 512
using namespace std;


int main()
{
    int num, base;
    LPDWORD bytesRead = 0;
    char result[50];
    char end[] = {"\0"};

    LPCTSTR Roura = TEXT("\\\\.\\pipe\\pipeline");

    HANDLE h = CreateNamedPipe(Roura, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, BUFFSIZE, BUFFSIZE, 0, NULL);


    assert(h != INVALID_HANDLE_VALUE);

    if (!ConnectNamedPipe(h, NULL)) return -1;

    while (true) {
        ReadFile(h, &num, BUFFSIZE, bytesRead, NULL);
        if (num == 0) {
            CloseHandle(h);
            return 0;
        }
        ReadFile(h, &base, BUFFSIZE, bytesRead, NULL);
        _itoa(num, result, base);
        WriteFile(h, result, strlen(result), NULL, NULL);
    }

    return 0;
}

【问题讨论】:

  • 你的error handling在哪里?
  • 首先检查错误。每个ReadFileWriteFile 都成功了吗?你不知道。如果失败,请致电GetLastError 找出原因。
  • @CareyGregory 我不明白为什么它在 Windows10 和 Windows7 中有效。
  • @ValentinEmilCudelcu 通过检查每个语句的成功与否并在失败时找到确切的错误,这将有助于告诉您为什么它在 Windows 10 中有效但在 Windows 7 中失败。
  • 您对ReadFile的使用完全错误并导致堆栈损坏

标签: c++ windows winapi windows-7 windows-10


【解决方案1】:
#define BUFFSIZE 512
int num, base;
LPDWORD bytesRead = 0;
ReadFile(h, &num, BUFFSIZE, bytesRead, NULL);

此代码完全错误。需要使用

int num, base;
DWORD bytesRead;
ReadFile(h, &num, sizeof(num), &bytesRead, NULL);

相反。 bytesRead== 0

如果 lpOverlapped 为 NULL,则 lpNumberOfBytesRead 不能为 NULL。

但是在 win7 上确实如此,但在 win10 上 - 系统让lpNumberOfBytesRead == 0 - 所以这里没有崩溃

还有这个

WriteFile(h, &num, sizeof(int), NULL, NULL);

再次 - 这里已经只有 1 个错误比较 ReadFile 调用

如果 lpOverlapped 为 NULL,则 lpNumberOfBytesWritten 不能为 NULL。

为什么?

它在 Windows 10 中有效,但在 Windows 7 中无效

这是因为从 ReadFile/WriteFile 的 win 8.1 代码开始(如果我没记错)检查 lpNumberOfBytes 参数,如果它 ==0 没有分配给它的实际数量读取或写入的字节数。但在 windows 7 系统上不做这个检查并无条件地按 0 地址写入数据

【讨论】:

  • 它还在崩溃!
  • (WriteFile(h, &amp;num, sizeof(int), NULL, NULL);) 我发现在这个 WriteFails 客户端崩溃之后
  • @ValentinEmilCudelcu - 当然出于同样的原因第三个参数是 0
  • @ValentinEmilCudelcu - 是的
  • @ValentinEmilCudelcu - 第 4 个参数 (lpNumberOfBytesWritten) 不能为 0。如果在函数声明中 LPDWORD lpNumberOfBytesWritten 这并不意味着您必须在自己的代码中声明 LPDWORD lpNumberOfBytesWritten - 这是基本的误解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
相关资源
最近更新 更多