Добого всем дня.
Нород,у меня вопрос по функции recv.Использую сырые сокеты и тип протокола — ICMP.
Посылаю пакет функцией sendto в одном потоке, а вот как принимаю во 2 потоке:
посылка
QueryPerformanceCounter(&tmp);
iTime[counter-1].start_time = tmp.QuadPart;
result = sendto (s, buffer, packet_length, 0,(struct sockaddr *)&target, sizeof (target));
Прием:
FreeOnTerminate = true;
SOCKET sock;
SOCKADDR_IN saddr;
u_long flags;
BYTE buf[MAX_PACKET_SIZE];
int cnt;
ip_header ip;
icmp_header* icmp_hed;
char caddr[128];
LARGE_INTEGER tmp;
sock = socket (PF_INET,SOCK_RAW,IPPROTO_IP);
if (sock == INVALID_SOCKET) return;
ZeroMemory(&saddr,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.S_un.S_addr = LocalAddrs[Form1->ComboBox1->ItemIndex];
bind(sock,(SOCKADDR*)&saddr,sizeof(SOCKADDR));
flags = 1;
ioctlsocket(sock,SIO_RCVALL,&flags);
while (true)
{
if (Terminated) break;
cnt = recv(sock,buf,sizeof(buf),0);
if (Terminated) break;
if (cnt>=sizeof(ip_header))
{
QueryPerformanceCounter(&tmp);
if (!CheckFilter(buf)) continue;
icmp_hed = (icmp_header*)(buf+sizeof(ip_header));
if (icmp_hed->ident == 4500)
{
iTime[icmp_hed->num-1].end_time = tmp.QuadPart;
iTime[icmp_hed->num-1].icmp_time = double(iTime[icmp_hed->num-1].end_time - iTime[icmp_hed->num-1].start_time)/double(frec.QuadPart);
iTime[icmp_hed->num-1].id = icmp_hed->num;
}
}
}
closesocket(sock);
Для контроля запускаю WireShark.
Все работает, но есть одна странность со срабатыванием функции recv:когда пакет фрагментирется,ну например его размер 10000, то при срабатывании функции recv я фиксирую время приема отклика и оно оказывается гораздо меньше чем время приема отклика в WireShark, например, для пакета длинной 15000 шарк зафиксировал время приема отклика 0.0042, а мое время равно 0.0023, которое почти равно времени приема первого фрагмента в шарке, хотя функция recv возвращает правильный и полный размер пакета,
почему эта функция так быстро возвращает управление ?