OverLapped I/O Socket 的问题,请教了! ( 积分: 200 )

  • 主题发起人 主题发起人 迷糊
  • 开始时间 开始时间
Scatter, Gather and MSG_PARTIAL

The multiple buffer (WSABUF) input arguments for WSARecv()/WSARecvFrom() and WSASend()/WSASendto() provide support for scatter and gather operations (similar to those in the readv() and writev() functions in BSD Unix). The MSG_PARTIAL flag might also do this, but the specification isn't entirely clear what the intended use of the flag is, and current implementations don't support it (as described below).

These operations are designed for datagram sockets that preserve message boundaries, not for stream sockets that do not (so may not fill buffers), though they do seem to work with stream sockets. The advantage that the gather operation provides is that it can assemble a single outgoing datagram from multiple buffers--e.g. put together different fields--and the scatter operation can "parse" fixed field lengths in an incoming datagram into multiple buffers.

WSARecv()/WSARecvFrom(): Works fine -- scatters to input buffers on both Win95 and NT4 with datagram sockets. Stream sockets also work on both Win95 and NT4 SP3 in the testing I've done (which I would not recommend, since with a TCP byte stream the spec doesn't indicate that each buffer must be filled to the specified size on scatters, so behavior may be unpredictable under some circumstances with stream sockets).

WSASend()/WSASendTo(): Works fine -- gathers from output buffers on both Win95 if you use datagram sockets. It also works with datagram sockets on NT4 SP3, although it failed with 10040 - WSAEMSGSIZE, if the message was larger than the MTU, so required IP fragmentation (e.g. greater than 1472 on Ethernet). This also works with stream sockets, but a similar warning as given for scatters goes for gathers as well (there's no guarantee that all bytes will be sent)



以下是 WSASend在UNIX下的实现:

sockapi int __stdcall WSASend
(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{
int rc;

TRACE("WSASend");

if (lpOverlapped != NULL) panic("Overlapped I/O not implemented in WSASend");
if (lpCompletionRoutine != NULL) panic("Completion routines not implemented in WSASend");

rc = writev(s, lpBuffers, dwBufferCount);
if (rc < 0) return -1;

if (lpNumberOfBytesSent) *lpNumberOfBytesSent = rc;
return 0;
}



WRITEV的解释:
NAME
readv, writev - read or write data into multiple buffers

SYNOPSIS
#include <sys/uio.h>

int readv(int filedes, const struct iovec *vector,
size_t count);

int writev(int filedes, const struct iovec *vector,
size_t count);

DESCRIPTION
The readv() function reads count blocks from the file
associated with the file descriptor filedes into the mul-
tiple buffers described by vector.

The writev() function writes at most count blocks
described by vector to the file associated with the file
descriptor vector.

The pointer vector points to a struct iovec defined in
<sys/uio.h> as

struct iovect
{
void *iovbase; /* Starting address */
size_t iov_len; /* Number of bytes */
} ;

Buffers are processed in the order vector[0], vector[1],
... vector[count].

The readv() function works just like read(2) except that
multiple buffers are filled.

The writev() function works just like write(2) except that
multiple buffers are written out.


看完了以上说明后,相信你会将WSASEND里面的dwBufferCount设为1吧!:)
 
谢谢painboy
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
后退
顶部