Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5597
  • Last Modified:

Winsock error: WSAEMSGSIZE (10040): ->buffer used to receive a datagram into was smaller than the datagram itself.

Background Info:

I am trying to write a program on Windows(WinSock) that creates 2 SOCK_DGRAMs that are binded to the same machine(My PC: 127.0.0.1). These two sockets need to work as follows:
1) listeningSocket(non-blocking mode)
2) sendingSocket(blocking mode/dont care)

I am trying to send a file thru the "sendingSocket" and
recieve the same file thru the "listeningSocket".

My file is 14990 bytes in size.
I read the file into an array sendBuffer[14990]
I have a corresponding recvBuffer[14990]
I determined the max buffer size of my system(8192 bytes) by doing a getsockopt().

Then i divide the total file size into chunks of 8192 bytes and send each chunk thru the "sendingSocket" (In this case i get 2 chunks: 1 whole chunk of 8192 bytes + 1 partial chunk of 6798 bytes).........this works fine!!

Similarly i receive these chunks from the listeningSocket. I receive the first whole chunk of 8192 bytes sucessfully..no problems!. But when I try to receive the partial chunk of 6798 bytes...i get the following error

WSAEMSGSIZE (10040): Message too long -> A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.

Problem/Question:
Why does recvfrom() fail on the partial chunk? I have also provided(below) the code for the send and receive functions.

please advise


-------- start code
//#####################################################################

int recv()
{
      // start receiving data from sendbuffer to bufrecv       
      int recv,totalrecv =0;
      SOCKADDR_IN from;     /* Sender's address. */
        fromlen = sizeof(from);
      
      getsockopt(listeningSocket,        
               SOL_SOCKET,        
               SO_RCVBUF,                        
               (char *)&sockbufsize,  
               &size);

      //following forloop receives byte chunks of size sockbufsize(8192 bytes)
      for (j=0; j<numread/sockbufsize; j++)
      {
            recv = recvfrom(listeningSocket,
                        bufrecv+j*sockbufsize,
                        sockbufsize,
                        MSG_PEEK,
                        (LPSOCKADDR)&from,
                        &fromlen);
            
            //check for receive errors
            if (recv == SOCKET_ERROR)
            {
                  nret = WSAGetLastError();
                  ReportError(nret, "recvfrom()");
                  WSACleanup();
                  return NETWORK_ERROR;
            }

            totalrecv = totalrecv + recv;
                              
      }

      // now take care of the last byte chunk that is less than sockbufsize(8192 bytes)
      
/***********Something wrong with the following statement...dont know why "recvfrom" fails and gives Error 10040 i.e "datagram read is larger than the buffer supplied"  Size of the datagram read -> "numread%sockbufsize".......this is exactly equal to the buffer supplied -> (bufrecv+j*sockbusize))******************/
      
      recv = recvfrom(listeningSocket,
                  bufrecv+j*sockbufsize,
                  numread%sockbufsize,
                  MSG_PEEK,
                  (LPSOCKADDR)&from,
                  &fromlen);


      
      //check for receive errors
      if (recv == SOCKET_ERROR)
      {
            nret = WSAGetLastError();
            ReportError(nret, "recvfrom()");
            WSACleanup();
            return NETWORK_ERROR;
      }
            
      totalrecv=totalrecv+recv;
      
}
//#####################################################################
int send()
{
      // Start sending and receiving data
          ///////  first determine the MTU ////////

      int    sockbufsize = 0;
      int    size = sizeof(int);

      int returntype = getsockopt(senderSocket,        
                         SOL_SOCKET,        
                        SO_SNDBUF,                        
                        (char *)&sockbufsize,  
                        &size                            
                        );


        ////// Send data from the sendbuffer in chunks //////
      
      //following for loop sends byte chunks of size sockbufsize(8192 bytes) from sendbuf
      for (i=0; i<numread/sockbufsize; i++)
      {
            sent = sendto(  senderSocket,
                        bufsend+i*sockbufsize,
                        sockbufsize,
                        MSG_DONTROUTE,
                        (LPSOCKADDR)&serverInfo,
                        sizeof(struct sockaddr));
            
            //check for send errors
            if (sent == SOCKET_ERROR)
            {
                  nret = WSAGetLastError();
                  ReportError(nret, "sendto()");
                  WSACleanup();
                  return NETWORK_ERROR;
            }

            totalsent=totalsent+sent;
      }
      
      // now take care of the last byte chunk that is less than sockbufsize(8192 bytes)

      sent = sendto(  senderSocket,
                  bufsend+i*sockbufsize,
                  numread%sockbufsize,
                  MSG_DONTROUTE,
                  (LPSOCKADDR)&serverInfo,
                  sizeof(struct sockaddr));

      //check for send errors
      if (sent == SOCKET_ERROR)
            {
                  nret = WSAGetLastError();
                  ReportError(nret, "sendto()");
                  WSACleanup();
                  return NETWORK_ERROR;
            }

      totalsent=totalsent+sent;

}



//#####################################################################

-------- end code

0
psudame
Asked:
psudame
1 Solution
 
jtblackburnCommented:
Try this.  I think memset will do it for you.

memset( RcvBuff, 0, sizeof( RcvBuff) );
nRet = recv( rsock, RcvBuff, sizeof( RcvBuff), 0);


where nRet = the error number

make sure you include memory.h

Good Luck

Jonathan
0
 
CleanupPingCommented:
psudame:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
dc197Commented:
This may also help with some background info:

http://www.winsock-error.com/10040.aspx
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now