WriteFile成功,即使缓冲区被挂起的操作覆盖
WriteFile succeeded even when buffer is overwritten for pending operation
在我的程序(发布到这个问题中)中,我在客户端进行了以下更改:
wretry:
cbToWrite = _stprintf(chBuf[0], TEXT("Message %d from Client"), retrycount - numberofsend + 1);
cbToWrite *= sizeof(TCHAR);
fSuccess = WriteFile(hPipe, chBuf[0], cbToWrite,
&cbWritten, &woverlapped[retrycount-numberofsend]);
这样一来,现在每次写入都将使用相同的缓冲区。
在这种情况下,WriteFile
每次都挂起,因为它返回ERROR_IO_PENDING
。由于缓冲区的内容每次都会被覆盖,服务器应该会收到写入缓冲区的最后一条消息。但服务器接收消息没有任何问题。
这是否意味着消息首先被复制到某个内部缓冲区?我可以销毁缓冲区并期望消息传递到服务器吗?
再次引用MSDN:
lpBuffer[in]指向包含要写入文件或设备的数据的缓冲区的指针。此缓冲区在写入操作期间必须保持有效。在写入操作完成之前,调用方不得使用此缓冲区。
因此,如果在进行写操作时损坏了缓冲区,那么您的消息似乎无法保证安全到达。您绝对不应该破坏缓冲区
您的代码本质上是在使用未定义的行为。来自WriteFile文档:
在写入操作使用缓冲区时访问输出缓冲区可能会导致从该缓冲区写入的数据损坏。在写入操作完成之前,应用程序不得写入、重新分配或释放写入操作正在使用的输出缓冲区。
正如Raymond Chen所指出的,看似成功是未定义的行为
未定义的行为意味着任何事情都可能发生。程序可能会立即崩溃。它可能在五分钟后坠毁。它可能会给你的老板发电子邮件,说你搞砸了,然后给你读《Vogon》的诗。也许不是。
您的代码现在可能可以工作,但可能在将来某个时候停止工作。这可能是因为你已经内置了版本,或者微软改变了WriteFile
的底层工作方式,或者是随机机会。
相关文章:
- 挂起和取消挂起一个文件DLL
- 如何防止C++遗留代码中的挂起指针
- 为什么所有C++编译器都会崩溃或挂起此代码
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- 构建挂起,即使是适度的文件大小
- 循环挂起迭代的 std::擦除 on std::list
- Poco::Net::FTPClientSession 在 open() 方法上挂起 129 秒,如果 ftp 主机不存
- Node.js fs.open() 在尝试打开 4 个以上的命名管道 (FIFO) 后挂起
- 从不同进程中的另一个线程挂起/恢复线程或进程
- Boost (Beast) websocket:同步写入挂起
- 为什么析构函数挂起
- 使用互斥会挂起程序
- 如何防止GUI挂起,同时允许第二次操作与Qt中的第一次操作一起执行
- closesocket()未完成IOCP的挂起操作
- QMutex是否需要是静态的,以便该类实例的其他线程调用知道要挂起它们的操作
- 显示MessageBox时,父窗口操作已挂起
- 如果 ssl::stream<tcp::socket 有挂起的操作,我是否不允许删除它>?
- 阻止取消Boost.Asio中挂起的异步操作
- 带有互锁操作的线程同步在Visual Studio 2013 c++原生代码中挂起
- WriteFile成功,即使缓冲区被挂起的操作覆盖