比如 sendto(s, buffer, 32000),  接收端是否会只接受到buffer部分数据的情况?

解决方案 »

  1.   

    sendto()的返回值是已发送的字节数。
      
    以下是MSDN的描述:
    sendto
    The sendto function sends data to a specific destination.int sendto(
      SOCKET s,
      const char* buf,
      int len,
      int flags,
      const struct sockaddr* to,
      int tolen
    );Parameters

    [in] Descriptor identifying a (possibly connected) socket. 
    buf 
    [in] Buffer containing the data to be transmitted. 
    len 
    [in] Length of the data in buf, in bytes. 
    flags 
    [in] Indicator specifying the way in which the call is made. 
    to 
    [in] Optional pointer to a sockaddr structure that contains the address of the target socket. 
    tolen 
    [in] Size of the address in to, in bytes. 
    Return Values
    If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
      

  2.   

    这是有可能的,如果接受方设置的buf空间不够容纳整个包,也没有声明MSG_PEEK标志,这个包就会被接受方截断,这个包剩下的部分丢失。
      

  3.   

    recvfrom FunctionThe recvfrom function receives a datagram and stores the source address.
    int recvfrom(
      __in          SOCKET s,
      __out         char* buf,
      __in          int len,
      __in          int flags,
      __out         struct sockaddr* from,
      __in_out      int* fromlen
    );Parameters

    Descriptor identifying a bound socket.buf 
    Buffer for the incoming data.len 
    Length of buf, in bytes.flags 
    Indicator specifying the way in which the call is made.from 
    Optional pointer to a buffer in a sockaddr structure that will hold the source address upon return.fromlen 
    Optional pointer to the size, in bytes, of the from buffer.Return Value
    If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.Error code Meaning 
    WSANOTINITIALISED
     A successful WSAStartup call must occur before using this function.
     
    WSAENETDOWN
     The network subsystem has failed.
     
    WSAEFAULT
     The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address.
     
    WSAEINTR
     The (blocking) call was canceled through WSACancelBlockingCall.
     
    WSAEINPROGRESS
     A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
     
    WSAEINVAL
     The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.
     
    WSAEISCONN
     The socket is connected. This function is not permitted with a connected socket, whether the socket is connection oriented or connectionless.
     
    WSAENETRESET
     The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.
     
    WSAENOTSOCK
     The descriptor is not a socket.
     
    WSAEOPNOTSUPP
     MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
     
    WSAESHUTDOWN
     The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.
     
    WSAEWOULDBLOCK
     The socket is ed as nonblocking and the recvfrom operation would block.
     
    WSAEMSGSIZE
     The message was too large to fit into the specified buffer and was truncated.
     
    WSAETIMEDOUT
     The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
     
    WSAECONNRESET
     The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket; it is no longer usable. On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message.
     Res
    The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which the data was sent. This function is typically used with connectionless sockets. The local address of the socket must be known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications. For client applications using this function, the socket can become bound implicitly to a local address through sendto, WSASendTo, or WSAJoinLeaf.For stream-oriented sockets such as those of type SOCK_STREAM, a call to recvfrom returns as much information as is currently available—up to the size of the buffer specified. If the socket has been configured for inline reception of OOB data (socket option SO_OOBINLINE) and OOB data is yet unread, only OOB data will be returned. The application can use the ioctlsocket or WSAIoctl SIOCATMARK command to determine whether any more OOB data remains to be read. The from and fromlen parameters are ignored for connection-oriented sockets.For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer specified. If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.If the from parameter is nonzero and the socket is not connection oriented, (type SOCK_DGRAM for example), the network address of the peer that sent the data is copied to the corresponding sockaddr structure. The value pointed to by fromlen is initialized to the size of this structure and is modified, on return, to indicate the actual size of the address stored in the sockaddr structure.If no incoming data is available at the socket, the recvfrom function blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect can be used to determine when more data arrives.If the socket is connection oriented and the remote side has shut down the connection gracefully, the call to recvfrom will complete immediately with zero bytes received. If the connection has been reset recvfrom will fail with the error WSAECONNRESET.The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by using the bitwise OR operator with any of the following values.Value Meaning 
    MSG_PEEK Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function subsequently returns the amount of data that can be read in a single call to the recvfrom (or recv) function, which may not be the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the recvfrom (or recv) function is limited to the data size written in the send or sendto function call. 
    MSG_OOB Processes Out Of Band (OOB) data. 
      

  4.   

    可能是我的描述不够清楚。发送和接受程序都是我自己的写的, 接收端的buffer足够大,并且能够receivefrom到数据.这种情况下, sendto一个数据包, receivefrom是否会存在只接受到部分数据的情况?(我希望的情况是, receivefrom要么接受不到任何数据,要么接受到完整的buffer数据)
      

  5.   

    当然有可能,不是你buffer大不大的,问题,UDP本身就有丢包的情况.
      

  6.   

    zzdmfk : 丢包的事情我知道, 我想问的是在同一个包中,会不会丢数据? 
      

  7.   

    UDP丢包是正常的,TCP是系统做的差错控制,UDP你得自己写。
      

  8.   

    UDP是数据报协议,从它的名字当中你就可以知道,既然是报文,同一个报文的数据要么全收要么全丢
    TCP是流协议,会收到部分报文,但收没收全可以通过查看参数知道
      

  9.   

    If the datagram or message is larger than the buffer supplied, the buffer is filled with the first part of the datagram, and recv generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost; for reliable protocols, the data is retained by the service provider until it is successfully read by calling recv with a large enough buffer. For TCP/IP, an application cannot receive from any multicast address until after becoming a group member.由于接收方的接收缓冲区不够大,对于UDP来说,超出部分的数据会丢失。
      

  10.   

    你期望接收方能够一次性完整的收到服务端发送的数据包。
    那是一种奢想。
    当你发送数据包比较小的时候,那样是可能的。但是,如果你发送的数据包比较大。
    现在假设客户端和服务端的网络收发栈的缓冲都是100KB,那么你客户端一次性发送200KB的数据,
    这时客户端的发送缓冲和服务端的接收缓冲都将一次性填满,
    你必须等待下一次的发送和接收,才能完成200KB的数据传输。
      

  11.   

    绝对不会。
    UDP要么收完,一个字节都不差,要么一个字节都不会返回到应用层。