WSASend投递,WSAGetLastError()得到错误代码 6

glacierful 2009-03-18 05:52:52
使用完成端口来编写的一个程序,使用WSASend来投递数据,返回值表示已经成功了。
在完成端口的服务线程中,GetQueuedCompletionStatus结果为False,使用WSAGetLastError查到的错误是6,搜了一下,其中有个回答是OVERLAPPED 里的hEvent无效,但我已经用WSACreateEvent赋值了。

str := Edit1.Text + chr($D);

new(PerIoData);
for k:= 1 to Length(str) do
PerIoData.Buffer[k-1] := str[k];

ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));
PerIoData.Overlapped.hEvent := WSACreateEvent();

PerIoData.DataBuf.buf := @PerIoData.Buffer;
PerIoData.DataBuf.len := DATA_BUFSIZE;//length(str);
PerIoData.IOType := ioWrite;


if (WSASend(m_socket, @(PerIoData.DataBuf), 1, @SendBytes, 0, @(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
self.Memo1.Lines.Add('WSASend() failed with error');
end;
end;



LPPER_IO_OPERATION_DATA = ^ PER_IO_OPERATION_DATA ;
PER_IO_OPERATION_DATA = packed record
Overlapped: WSAOVERLAPPED;
DataBuf: TWSABUF;
Buffer: array [0..DATA_BUFSIZE] of CHAR;
BytesSEND: DWORD;
BytesRECV: DWORD;

IOType :TIOType;
end;
...全文
343 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
glacierful 2009-03-19
  • 打赏
  • 举报
回复
不过在完成端口句柄无效的情况下,GetQueuedCompletionStatus无法阻塞线程,这个问题挺奇怪的。
glacierful 2009-03-19
  • 打赏
  • 举报
回复
谢谢两位,真的是m_hCompletionPort的初始化没有成功,两位太厉害了。
我一开始是这样初始化的,CreateIoCompletionPort(INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0),因为第二个参数ExistingCompletionPort: THandle的类型是个句柄值,所以我就传了一个NVALID_HANDLE_VALUE。把这个参数传个0就正常了,就像下边这样:
CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);

因为这个过程挺简单的,我都没有想到去检查这个地方。
再次感谢两位,帮了我大忙了。
cnzdgs 2009-03-18
  • 打赏
  • 举报
回复
调试看一下m_hCompletionPort是否正确。
僵哥 2009-03-18
  • 打赏
  • 举报
回复
m_hCompletionPort有实始化吗?
glacierful 2009-03-18
  • 打赏
  • 举报
回复
while not Terminated do
begin
getData := GetQueuedCompletionStatus(m_hCompletionPort, BytesTransferred,
DWORD(PerHandleData), POverlapped(PerIoData), INFINITE);

if getData then
....
else
...

end

getData永远都返回False,PerIoData值为nil。不知道是不是WSASend的时候,PerIoData内存没有分配到堆上,还是什么别的原因。
glacierful 2009-03-18
  • 打赏
  • 举报
回复
在完成端口的服务线程里边调用GetQueuedCompletionStatus的时候,没有数据的时候,GetQueuedCompletionStatus也不会阻塞,这种情况是不是错的?
我跟踪了几次,GetQueuedCompletionStatus每次的返回了false,根本就没有成功过,这令我很困惑。
cnzdgs 2009-03-18
  • 打赏
  • 举报
回复
把GetQueuedCompletionStatus相关代码贴上。
僵哥 2009-03-18
  • 打赏
  • 举报
回复
另外,错误码实际上存于线程局部存储当中的,当操作成功时,错误码有可能不会被重置,甚至还有可能影响正常的作业,为防止线程内错误码被缓存而影响正常的作业,在线程调用GetQueuedCompletionStatus前最好使用SetLastError(0)
僵哥 2009-03-18
  • 打赏
  • 举报
回复
使用GetQueuedCompletionStatus时,是不需要hEvent的.

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧