Click here to Skip to main content
15,902,189 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello ..

I am working on an application that wants me to read data from the Ethernet port at 15 MB/sec. The server is sending a data in packets of 804 Bytes each.

When I try to read 1000 packets one after the other using recvfrom() it throws SOCKET_ERROR after every 20-25 packets. This is probably happening because the data is coming at slower speed and we are not putting any time delay between two consecutive recvfrom() calls.

Then we cross verified our observation by introducing a delay of 1 m sec in between two calls of recvfrom(). It never throws errors, probably because the data is always ready in the buffer (in this case).

But in actual our requirement we can't put such a big delay in-between consecutive recvfrom() calls. The we tried setting the recieve timeout for recvfrom() using select() function. It did not help probably because sockets by default are non-blocking in nature.Kindly let us know what we can do in this regard:

Will converting my socket from non-blocking to blocking help? If yes, how can i do this?

Anybody Please help .. I am stuck very badly..

Regards
Posted
Comments
Sergey Alexandrovich Kryukov 19-Mar-13 9:55am    
Yes... the strategy you describe looks very unreliable in principle.
Maybe, if you explain the ultimate purpose of it and more general architecture, it may help...
—SA
Jochen Arndt 19-Mar-13 10:24am    
You should show us how you receive the data. Did you use overlapped I/O? This is recommended and should work if properly implemented.
debarunb 19-Mar-13 11:15am    
Ultimate purpose of the application is to receive UDP packets from a FPGA based development kit @ 16MB/sec.

Actual scenario is :
1. The development kit is sending UDP packets each containing 804 Bytes of data at a rate of 16MB/sec.
2. We are using recvfrom() function and putting the received data in Data_Out.txt file. Using size of the file created after a period of 50 sec , we concluded that the receiving speed is exactly same as that of transmission speed. (15 MB/sec)
3. We are capturing the packets simultaneously using wireshark also, for cross verification.
4. Initial 10 packets received by wireshark are found to be exactly same as that recvfrom() {inside the Data_Out.txt }
5. But as we go on checking, there are many places of mismatch between the two data sets.

So we are not able to find a reason behind this mismatch. If we were losing some packets it could have reduced the size of the Data_Out.txt considerably.(this is my opinion, as we are capturing data for around 50 secs, a considerable amount of time)

I fear we are doing some mishandling with the winsock API. So kindly have a look at the usage pasted below:

----------------------------------------------------------------------------------------------
CString TimeString1,TimeString2,TimeString3,TimeString4;
SOCKADDR_IN saddr;
sockaddr_in saddr1;
int length= sizeof(saddr1);
BYTE a0,a1,a2,a3;
CString addr;
Thread_Param->mDlg_Handle->m_remote_ip.GetAddress(a0,a1,a2,a3);
addr.Format(L"%u.%u.%u.%u",a0,a1,a2,a3);
char *addrchar= new char[addr.GetLength()+1];
wcstombs(addrchar,addr,addr.GetLength()+1);
saddr.sin_family=AF_INET;
saddr.sin_addr.s_addr=inet_addr(addrchar);
saddr.sin_port=htons(Thread_Param->mDlg_Handle->m_remote_udp_port);//temp_dlg->m_remote_udp_port

fd_set fds;
int n;
struct timeval tv;
FD_ZERO(&fds);
FD_SET(Thread_Param->mDlg_Handle->m_socket,&fds);
tv.tv_sec=0;
tv.tv_sec=110;
n=select(Thread_Param->mDlg_Handle->m_socket,&fds,NULL,NULL,&tv);

if(n==0)
{
AfxMessageBox(_T("TimeOut Set !!"));
}
else
{
AfxMessageBox(_T("Error !!"));

}
///////////////////////////////////////////////////////////////////////////////////////////////////////

int Total_recd=0;
int addrlen=sizeof(saddr);
int count=0;
char *Recv_Buff="";

int flag_fail;
#define TIME_OUT_LIMIT 40

int i=0;
while(i<400000)
{
recd=recvfrom(Thread_Param->mDlg_Handle->m_socket,RecvBuff1,804,0,(struct sockaddr *)&saddr, &addrlen);
if(recd!=804)
{
CString strMsg2;
strMsg2.Format(L"%d",recd);
if(recd!=-1)
{
AfxMessageBox(strMsg2+_T("Data not Received Properly !!!"),MB_ICONERROR);
}

}
else
{
count=count+recd;
i++;
fwrite(&RecvBuff1,1,recd,fp_out);
}


}

CString strmsg;
strmsg.Format(L"%d",count);
fclose(fp_out);
AfxMessageBox(strmsg+_T("Completed"));

-------------------------------------------------------------------------------------
Jochen Arndt 19-Mar-13 12:51pm    
You may add the relevant code parts properly formatted to your question using the 'Improve Question' link. It's hard to read the code here.

The first option is to get the error code using WSAGetLastError() when recfrom() fails. This may help in isolating the problem.

A general option is to use overlapped IO (WSARecvFrom() with overlapped struct instead recvfrom() and other WSA... functions). This will result in more code but is generally more stable.

With overlapped IO, WSARecvFrom() returns immediately when the requested number of data is available. If not, WSAGetLastError() is ERROR_IO_PENDING. Then call WaitFor[Single|Multiple]Object and WSAGetOverlappedResult() when the wait function returns with the overlapped event.
debarunb 20-Mar-13 8:06am    
hi sir
I am trying to point out my error after receiving packets by writing error codes in a switch statement.And I got an socket error i.e "WSAEWOULDBLOCK"(Resource Temporarily Unavailable)
But I don't know why this error happens please help me please..

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900