发布网友 发布时间:2022-04-22 08:45
共1个回答
热心网友 时间:2023-11-14 03:26
WSASend覆盖标准的send函数,并在下面两个方面有所增强:
>它可以用于overlapped socket(重叠socket)上以进行重叠发送的操作(简单地理解为就是异步send也可以了)
>它可以一次发送多个缓冲区中的数据来进行集中写入。应该相当于unix上的writev,好处看来是避免Nagle算法。
WSASend用于在一个面向连接的socket(第一个参数s)上发出的数据。It can also be used, however, onconnectionless sockets that have a stipulated default peer address established through theconnectorWSAConnectfunction.
对于overlapped sockets来说 (通过WSASocket函数,用WSA_FLAG_OVERLAPPED标示创建),发送消息时使用的是重叠IO(overlapped I/O), 除非lpOverlapped and lpCompletionRoutine 都是NULL. 这时, 这个socket被视为非重叠的socket. 当所有的缓冲区都被发送完成了,将会执行一个动作来表示操作完成,这个动作可能是调用完成例程或者是引发一个event对象。如果操作没有立即完成, 最终的完成状态通过完成例程或者 WSAGetOverlappedResult得到
对于非重叠的sockets来说, 最后两个参数(lpOverlapped, lpCompletionRoutine) 被忽略,WSASend 和 send具有同样的语意。数据从用户缓冲区拷贝到发送缓冲区中(应该是指系统的socket堆栈)。如果socket是非阻塞的又是同时是面向流的(简单地理解为tcp), 同时发送缓冲区没有足够的大小, WSASend将只发送用户缓冲区中的部分数据。 如果同样缓存大小,而socke是阻塞的socket, WSASend将阻塞直到用户所有的数据被发送成功。
Note socket配置项SO_RCVTIMEO and SO_SNDTIMEO只能被用于阻塞的sockets。
lpBuffers这个参数是一个指针,它指向一个WSABUF结构的数组。这个数组可以是瞬态的(transient)。所谓瞬态的含义如下:如果这个操作时重叠的操作,服务提供者有责任在这个调用返回之前保存WSABUF数组。这允许用户的应用使用一个基于栈的WSABUF数组。就是说你可以定义一个局部变量,当wsasend返回后如果是重叠IO呢,你的函数局部变量已经被销毁了(例如你的函数已经返回了)。系统实际上还没发送数据呢,那你不要担心,系统会保存这个数组的副本。
对于面向消息的socket(UDP?), 不要超过下层协议的最大消息大小,这个值可以通过SO_MAX_MSG_SIZE这个socket配置项得到。如果数据太长无法原子地发送,返回WSAEMSGSIZE, 没有数据发送成功。
Windows Me/98/95:TheWSASendfunction does not support more than 16 buffers.
NoteWSASend的成功完成不代表数据已经发送成功。