菜鸟 关于WSASend 函数,IO完成端口模型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了菜鸟 关于WSASend 函数,IO完成端口模型相关的知识,希望对你有一定的参考价值。
WSABUF myWSABUF;
myWSABUF.buf = "love you";
myWSABUF.len = 1024;
DWORD myReceive;
PPER_IO_DATA mypPerIO = (PPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
WSASend(pPerHandle->s,&myWSABUF,1,&myReceive,0,&mypPerIO->ol,NULL);
1.如上代码的功能是向客户端发送一个“love you ” 字符串。我是在别人写的一段 IOCP socket 模型 上改的, 我用 WSASend 函数向客户端发送信息, 客户端能正常收到 “love you”,但是, 除了 能 收到 “love you” 外, 还收到了很多很多空格,这是为什么?
2. 把 myWSABUF.len = 1024; 改为 myWSABUF.len = sizeof(myWSABUF.buf) 为什么 客户端 就收不到任何信息了?
myWSABUF.len 代表的难道不是我发送的love you 这个字符串的长度吗?
3.我在书上看到:WSASend 倒数第二个参数,即: &mypPerIO->ol 即代表了 WSAOVERLAPPED 的结构的指针, 那么,我自己写一个OVERLAPPED结构,如下
OVERLAPPED myOVERLAPPED
WSASend(pPerHandle->s,&myWSABUF,1,&myReceive,0,&myOVERLAPPED,NULL);
为什么客户端 就 收不到 任何 内容了呢? OVERLAPPED为什么必须放在一个 PER_IO 结构体里面呢?
我是菜鸟中的菜鸟,刚开始学套接字的异步IO , 很多很多 的地方 都很迷惑。 IOCP模型的原理我基本了解了, 但是就是很疑惑他们传值的方法, 又是什么 OVERLAPPED结构, 又是 PER_HANDLE的,真的很晕。
请各位给我理下思路啊,谢谢
2 你将sizeof(myWSABUF.buf)输入看看长度为多少?如果长度为8之对了一半,别忘了,字符结尾应该加上"\0"哦。
3 你只贴出了代码片段,无法判断错与对,建议你发送数据的时候先发送包头,如:建立一个结构体,
struct head_info
int head_type;//包体内容
int head_len;//包体长度
;
这个结构体长度的大小为为8,里面有包体的内容和包体的长度,接收时先接受包头的8字节长度,然后进行分析,再根据分析的接头接受包体就行了。追问
感觉您比较专业,麻烦再帮我看看这个问题,感谢!http://zhidao.baidu.com/question/261665634.html?fr=middle_ask
追答WSABUF buf; //定义一个WSABUF,名称叫buf
PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR,sizeof(PER_IO_DATA));
//定义并初始一个PPER_IO_DATA,名称叫pPerIO
buf.buf = pPerIO->buf;//将buf的buf指向pPerlO的buf中,也就是将buf的缓冲区指向了pPerIO的缓冲区。
对于你的疑惑:
1我没有完整的代码,你要弄明白buf.buf使用的缓冲区究竟是在接收前还是接收数据后,也就是指向pPerIO->buf是接收之前还是数据接收之后.
2 buf.buf的缓冲区指向了struct _PER_IO_DATA结构体的buf中,并不表示数据的转移,而是buf的缓冲区就是使用struct _PER_IO_DATA的缓冲区,而避免数据的拷贝,这样接受的数据就直接接收到了struct _PER_IO_DATA的BUF中了。
如果想获取长度应该是strlen((char*)myWSABUF.buf)吧?!! 参考技术B fdgdfgfdgdfg
IOCP:内核如何决定同步或异步完成 WSASend?
【中文标题】IOCP:内核如何决定同步或异步完成 WSASend?【英文标题】:IOCP: how does the kernel decide to complete WSASend synchronously or asynchronously? 【发布时间】:2014-11-03 02:44:29 【问题描述】:我们编写了利用 I/O 完成端口的软件,并在 SOCKET 对象上使用 WSASend,在命名管道上使用 WriteFile。
在这两种情况下,我们发现这些 API 返回 SOCKET_ERROR / WAS_IO_PENDING [1] 的时间比我们预期的要快得多(或命名管道 WriteFile 操作的等价物)。
似乎我们错误地假设如果我们填满发送缓冲区(CreateNamedPipe 中的 nInBufferSize)会触发异步完成,相反它似乎更具侵略性并且与发送缓冲区的大小无关。对于套接字和命名管道,如果足够快,大发送缓冲区(100k+)和小消息(几个字节)总是会在第二次写入时异步完成。
谁能证实这一点?有没有人知道 Windows 实现在决定何时异步完成 I/O 操作时遵循的启发式信息,而不是同步完成?
[1] "如果重叠操作成功启动并稍后完成,WSASend 返回 SOCKET_ERROR 并指示错误代码 WSA_IO_PENDING。" - http://msdn.microsoft.com/en-us/library/windows/desktop/ms742203(v=vs.85).aspx
【问题讨论】:
此类实施细节可能会发生变化。您需要确保您的代码不包含任何关于它们的假设。 【参考方案1】:为什么你认为你需要知道或关心。它不是 API 的记录部分,它可能受到当时堆栈中的驱动程序和任何分层服务提供程序的影响。
您必须编写正确的代码来处理成功的“同步”发送或待处理的“异步”发送,那么这对您获得这两种结果的频率有何影响?
此外,除非您使用 SetFileCompletionNotificationModes() 启用 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
,否则同步和待处理结果使用相同的代码路径。
【讨论】:
以上是关于菜鸟 关于WSASend 函数,IO完成端口模型的主要内容,如果未能解决你的问题,请参考以下文章
io 完成端口问题,每个 GetQueuedCompletionStatus 调用多个 wsarecv 或 wsasend
如果在 IOCP 模型中指定了 WSASend 的 lpCompletionRoutine 怎么办?
具有多个缓冲区的 WSASend() - 可以完成不完整吗?