Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: MFC VC++
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 19-Mar-13 4:13am
debarunb1.1K
Comments
Sergey Alexandrovich Kryukov at 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 at 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 at 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 at 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 at 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..
Jochen Arndt at 20-Mar-13 8:22am
   
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx.
 
There are no data available at the moment. WSAEWOULDBLOCK is similar to WSA_IO_PENDING (same as ERROR_IO_PENDING) when using overlapped IO. With overlapped IO you can then wait for data as described in my above post.
 
If you don't want to implement overlapped IO, wait a short time and call recv() again. If the total wait time until your last successful receive reaches your timeout limit, terminate with a timeout error.
 
But again: Using overlapped IO is the better choice. It is more flexible and produces less system load.
debarunb at 21-Mar-13 5:11am
   
sir
Can u give me any code example of Overlapped UDP socket??..
debarunb at 21-Mar-13 7:49am
   
@ Jochen Hi
I am using Overlapped IO Socket to receive data but its gives me an error "WSAWaitForMultipleEvents failed with error" so my question is how to solve this issue
My codes are below
/////////////////////////////////////////////////////////////////////////////////////
WSADATA wsaData;
WSABUF DataBuf;
WSAOVERLAPPED Overlapped;
 
SOCKET RecvSocket = INVALID_SOCKET;
struct sockaddr_in RecvAddr;
struct sockaddr_in SenderAddr;
 

FILE *fp_out=fopen("Data_Out.txt","wb");
int SenderAddrSize = sizeof (SenderAddr);
u_short Port = 21845;
 
char RecvBuf[804];
int BufLen = 804;
DWORD BytesRecv = 0;
DWORD Flags = 0;
 
int err = 0;
int rc;
int retval = 0;
 
rc = WSARecvFrom(RecvSocket,
&DataBuf,
1,
&BytesRecv,
&Flags,
(SOCKADDR *) & SenderAddr,
&SenderAddrSize, &Overlapped, NULL);
 
if (rc != 0)
{
err = WSAGetLastError();
if (err != WSA_IO_PENDING)
{

AfxMessageBox(_T("WSARecvFrom failed with error WSA_IO_PENDING"));
WSACloseEvent(Overlapped.hEvent);
closesocket(RecvSocket);
WSACleanup();
return 1;
}
else
{
 
rc = WSAWaitForMultipleEvents(1, &Overlapped.hEvent, TRUE, INFINITE, TRUE);
if (rc == WSA_WAIT_FAILED)
{
wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
retval = 1;
}
 
rc = WSAGetOverlappedResult(RecvSocket, &Overlapped, &BytesRecv,
FALSE, &Flags);
if (rc == FALSE)
{

AfxMessageBox(_T("WSArecvFrom failed with error WSAGetOverlappedResult:"));
retval = 1;
}
else
fwrite(DataBuf.buf,1,804,fp_out);



}

}
loop++;
 


}
AfxMessageBox(_T("Process Completed !!!"));
CString strmsg;
strmsg.Format(L"%d",count);
fclose(fp_out);
AfxMessageBox(strmsg+_T("Completed"));
///////////////////////////////////////////////////////////////////////////////////////
 
Please help...
debarunb at 22-Mar-13 1:16am
   
@Jochen Hi
Sir
1.)I am using Overlapped UDP Socket.
2.)Now I solved my previous error i.e.("WSAWaitForMultipleEvents failed with error").
2.)Now receiving speed is exactly same as transmission speed 16MBbs.
3.)But checking the text file again data loss happens.
 
My codes are given below
///////////////////////////////////////////////////////////////////////////////////////
fp_out=fopen("Data_Out.txt","wb");
CString TimeString1,TimeString2,TimeString3,TimeString4;
SOCKADDR_IN saddr;
sockaddr_in saddr1;
int length= sizeof(saddr1);
int length1=sizeof(saddr);
BYTE a0,a1,a2,a3;
CString addr;
//temp_dlg->m_remote_ip.GetAddress(a0,a1,a2,a3);
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

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

int flag_fail;
int nError=-1;

int i=0;
int loop=0;
DataBuf.len = BufLen;
DataBuf.buf = RecvBuf;
 

while(loop<=400000)
{
rc = WSARecvFrom(RecvSocket,
&DataBuf,
1,
&BytesRecv,
&Flags,
(SOCKADDR *) & saddr,
&length1, &Overlapped, NULL);
 
if (rc != 0)
{
err = WSAGetLastError();
if (err != WSA_IO_PENDING)
{
wprintf(L"WSARecvFrom failed with error: %ld\n", err);

WSACloseEvent(Overlapped.hEvent);
closesocket(RecvSocket);
WSACleanup();
return 1;
}
}



 
rc = WSAWaitForMultipleEvents(1, &Overlapped.hEvent, TRUE, INFINITE, TRUE);
if (rc == WSA_WAIT_FAILED)
{
//wprintf(L"WSAWaitForMultipleEvents failed with error: %d\n", WSAGetLastError());
AfxMessageBox(_T("WSAWaitForMultipleEvents failed with error:"));
retval = 1;
}
 
rc = WSAGetOverlappedResult(RecvSocket, &Overlapped, &BytesRecv,
FALSE, &Flags);
if (rc == FALSE)
{
//wprintf(L"WSArecvFrom failed with error: %d\n", WSAGetLastError());
AfxMessageBox(_T("WSArecvFrom failed with error WSAGetOverlappedResult:"));
retval = 1;
}




fwrite(DataBuf.buf,1,804,fp_out);
loop++;
 


}
AfxMessageBox(_T("Process Completed !!!"));
CString strmsg;
strmsg.Format(L"%d",loop);
fclose(fp_out);
AfxMessageBox(strmsg+_T("Completed"));
return TRUE;
///////////////////////////////////////////////////////////////////////////////////////
Please give me any suggestion.....

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

  Print Answers RSS
0 George Jonsson 215
1 Kornfeld Eliyahu Peter 169
2 OriginalGriff 120
3 PIEBALDconsult 110
4 BillWoodruff 85
0 OriginalGriff 6,165
1 DamithSL 4,658
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,649
4 Sergey Alexandrovich Kryukov 3,294


Advertise | Privacy | Mobile
Web03 | 2.8.141220.1 | Last Updated 19 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100