Подскажите как программно получить размер пакета на С++
Господа подскажите какой Апишной функцией мне воспользоваться чтобы программно получить размер TCP пакета в сети. ОС WIN XP SP2. Язык программирования С++ Builder.
Имеется ввиду максимальный допустимый размер пакета для сети? Или определенного пакета?
Да максимальная длина пакета
http://www.rusfaq.ru/?Step=info&Action=Question&ID=11217
Судя по содержанию этой ссылки - читать нужно с реестра.
Да максимальная длина пакета
Тогда это MTU, если я тебя правильно понял. И соответственно не имеет ни какого отношения к TCP, т.к. MTU - это канальный уровень. А TCP - транспортный. Они даже не соседи :)
И тем более сомнительно что он будет находится в реестре, во всяком случае у меня его почему-то не обнаружилось в указанных ветках. В разных сетях он может быть различный (у меня например - 1472) и навряд винда будет писать его в реестр. Хотя может и ошибаюсь конечно.
Можешь вручную его узнать, и затем уже плясать от этого значения.
Тогда это MTU, если я тебя правильно понял. И соответственно не имеет ни какого отношения к TCP, т.к. MTU - это канальный уровень. А TCP - транспортный. Они даже не соседи :)
И тем более сомнительно что он будет находится в реестре, во всяком случае у меня его почему-то не обнаружилось в указанных ветках. В разных сетях он может быть различный (у меня например - 1472) и навряд винда будет писать его в реестр. Хотя может и ошибаюсь конечно.
Можешь вручную его узнать, и затем уже плясать от этого значения.
Тогда, если уже брать только TCP, о размере пакета и беспокоиться не нужно. IP сам разбивает их. А на уровне TCP хоть гигабайт отправляй. :)
Тогда, если уже брать только TCP, о размере пакета и беспокоиться не нужно. IP сам разбивает их. А на уровне TCP хоть гигабайт отправляй. :)
О как!
Что-то я всегда считал, что фрагментацие пакетов занимается именно транспортный уровень, т.е. TCP. А "подписыванием" адресов на пакетах - протоколы сетевого уровня, т.е. IP.
И уж ни как не догадывался о том, что IP что-то фрагментировать может!
Мне кажется кто-то путает размер кадра канального уровня (Ethernet) и размер пакета транспортного уровня.
Тогда это MTU, если я тебя правильно понял. И соответственно не имеет ни какого отношения к TCP, т.к. MTU - это канальный уровень. А TCP - транспортный. Они даже не соседи :)
И тем более сомнительно что он будет находится в реестре, во всяком случае у меня его почему-то не обнаружилось в указанных ветках. В разных сетях он может быть различный (у меня например - 1472) и навряд винда будет писать его в реестр. Хотя может и ошибаюсь конечно.
Можешь вручную его узнать, и затем уже плясать от этого значения.
Итак. Для протокола TCP максимальный размер пакета задается MMS (maximum segment size). Что бы его выщитать (на мой взляд) нужно: взять, все таки, MTU минус фиксированные размеры IP и TCP заголовков. В Ethernet при IPv4 єто - 1460, IPv6 - 1440.
Итак. Для протокола TCP максимальный размер пакета задается MMS (maximum segment size). Что бы его выщитать (на мой взляд) нужно: взять, все таки, MTU минус фиксированные размеры IP и TCP заголовков. В Ethernet при IPv4 єто - 1460, IPv6 - 1440.
Ну, но я не про то. Тут кто-то недавно говорил что " на уровне TCP хоть гигабайт отправляй" и "IP сам разбивает их"
Я про это.
получается так количество пакетов * размер.
Народ, я просто имею колличество отправленых пакетов, мне нужно узнать сколько это в байтах
получается так количество пакетов * размер.
Так бы сразу и сказал. Ты как только сказал, так я сразу и понял, как это узнать :) Как мне кажется, размер пакета тебе нужен что бы узнать сколько передано информации? Если так, то это можно сделать без доподнительного мозкокопания.
Есть функция GetIfEntry(...): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/getifentry.asp
И структура для нее MIB_IFROW:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mib/mib/mib_ifrow.asp
В результате ты получишь и кол-во пакетов, и кол-во октетов (читай байт), и много еще чего. Если уж тебе так нужен этот размер, то можно поделить кол-во пакетов, на кол-во октетов. Прям стихи получились :)
:)
Может количество пакетов всё таки умножить на количество октетов? иначе получается слишком мало
:)
Тьфу блин, совсем закрутился, места перепутал! Ты кстати тоже не прав :) Надо количество октетов поделить на количество пакетов.
я получаю информацию о трафике в пакетах такое бывает что октеты 2562 а пакетов уже 41234. Информацию по пакетам получаю по широковещательным адресам.
Слушай получается тожа лажа. Проблема вот в чем
я получаю информацию о трафике в пакетах такое бывает что октеты 2562 а пакетов уже 41234. Информацию по пакетам получаю по широковещательным адресам.
Как получаешь индекс интерфейса с которого гребешь инфу?
Приведи пример кода. Я юзал эту функцию, но не для определения количества переданной информации. Дома проверю, если не забуду. Но ты свой пример то же выложи - как раз мне придет уведомление на мыло, вот и вспомню.
#include <vcl.h>
#include <stdio.h>
#include <windows.h>
#include <iphlpapi.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
PMIB_IFTABLE ifTable;
PMIB_IFROW pMibIfRow;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
// Allocate memory for our pointers.
ifTable = (MIB_IFTABLE*) malloc(sizeof(MIB_IFTABLE));
pMibIfRow = (MIB_IFROW*) malloc(sizeof(MIB_IFROW));
// Before calling GetIfEntry, we call GetIfTable to make
// sure there are entries to get.
// Make an initial call to GetIfTable to get the
// necessary size into dwSize
if (GetIfTable(ifTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
GlobalFree(ifTable);
ifTable = (MIB_IFTABLE *) malloc (dwSize);
}
// Make a second call to GetIfTable to get the actual
// data we want.
if ((dwRetVal = GetIfTable(ifTable, &dwSize, 0)) == NO_ERROR) {
if (ifTable->dwNumEntries > 0) {
pMibIfRow->dwIndex = 1;
if ((dwRetVal = GetIfEntry(pMibIfRow)) == NO_ERROR)
{
Edit8 ->Text = LPSTR(pMibIfRow->bDescr);
}
else {
Edit9 ->Text = "GetIfEntry failed";
// Here you can use FormatMessage to find out why
// it failed.
}
}
}
else {
Edit10 ->Text ="GetIfTable failed";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
//-------------Icmp Statistic -----------------------
PMIB_ICMP pIcmpStats;
pIcmpStats = (MIB_ICMP*) malloc(sizeof(MIB_ICMP));
if (GetIcmpStatistics(pIcmpStats) == NO_ERROR)
{
Edit1->Text = pIcmpStats->stats.icmpInStats.dwMsgs;
Edit2->Text = pIcmpStats->stats.icmpOutStats.dwMsgs;
}
//--------------------TCP Statistic -----------------
PMIB_TCPSTATS pTCPStats;
DWORD dwRetVal = 0;
pTCPStats = (MIB_TCPSTATS*) malloc (sizeof(MIB_TCPSTATS));
if ((dwRetVal = GetTcpStatistics(pTCPStats)) == NO_ERROR)
{
Edit3->Text = pTCPStats->dwActiveOpens;
Edit4->Text = pTCPStats->dwPassiveOpens;
Edit5->Text = pTCPStats->dwInSegs;
Edit6->Text = pTCPStats->dwOutSegs;
Edit7->Text = pTCPStats->dwNumConns;
}
else {
printf("Error getting TCP Stats.\n");
LPVOID lpMsgBuf;
if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
Edit7->Text = (char)(lpMsgBuf);
}
LocalFree( lpMsgBuf );
}
//--------------- IP Statistics -------------------------------------
PMIB_IPSTATS pIPStats;
DWORD dwRetVal2 = 0;
pIPStats = (MIB_IPSTATS*) malloc (sizeof(MIB_IPSTATS));
if ((dwRetVal2 = GetIpStatistics(pIPStats)) == NO_ERROR)
{
Edit8->Text = pIPStats->dwInReceives;
}
else {
printf("Error getting TCP Stats.\n");
LPVOID lpMsgBuf;
if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
Edit7->Text = (char)(lpMsgBuf);
}
LocalFree( lpMsgBuf );
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*
PMIB_IPMCAST_IF_ENTRY pIPStats;
pIPStats = (MIB_IPMCAST_IF_ENTRY*) malloc (sizeof(MIB_IPMCAST_IF_ENTRY));
if ((dwRetVal2 = GetIpStatistics(pIPStats)) == NO_ERROR)
{
Edit14->Text = IntToStr(pIPStats->ulInMcastOctets);
Edit15->Text = IntToStr(pIPStats->ulOutMcastOctets);
} */
}
//-----------------------GetUdpStatistics--------------------------
PMIB_UDPSTATS pUDPStats;
DWORD dwRetVal3 = 0;
pUDPStats = (MIB_UDPSTATS*) malloc (sizeof(MIB_UDPSTATS));
if ((dwRetVal3 = GetUdpStatistics(pUDPStats)) == NO_ERROR)
{
Edit9->Text = pUDPStats->dwInDatagrams;
Edit10->Text = pUDPStats->dwOutDatagrams;
}
else {
printf("Error getting TCP Stats.\n");
LPVOID lpMsgBuf;
if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
Edit7->Text = (char)(lpMsgBuf);
}
LocalFree( lpMsgBuf );
}
Edit11->Text= FloatToStr(StrToFloat(Edit1->Text) + StrToFloat(Edit5->Text) + StrToFloat(Edit8->Text)+ StrToFloat(Edit9->Text));
Edit12->Text= FloatToStr(StrToFloat(Edit2->Text) + StrToFloat(Edit6->Text) + StrToFloat(Edit10->Text));
Edit13->Text= FloatToStr(StrToFloat(Edit11->Text)+ StrToFloat(Edit12->Text));
}
Надо всего то было зайти на msdn и посмотреть их примеры. Вот код, который составлен по этим примерам с минимальной отсебятиной:
#include "Iphlpapi.h"
#include <stdio.h>
int main(void)
{
// Declare and initialize variables
PMIB_IFTABLE ifTable;
PMIB_IFROW pMibIfRow;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
// Allocate memory for our pointers
ifTable = (MIB_IFTABLE*) malloc(sizeof(MIB_IFTABLE));
// Make an initial call to GetIfTable to get the
// necessary size into the dwSize variable
if (GetIfTable(ifTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
{
GlobalFree(ifTable);
ifTable = (MIB_IFTABLE *) malloc (dwSize);
}
// Make a second call to GetIfTable to get the
// actual data we want
if ((dwRetVal = GetIfTable(ifTable, &dwSize, 0)) == NO_ERROR)
{
printf("Number of entries: %ld\n\n", ifTable->dwNumEntries);
}
else
{
printf("\tGetIfTable failed.\n");
return 1;
}
// Allocate memory for our pointer.
pMibIfRow = (MIB_IFROW*) malloc(sizeof(MIB_IFROW));
if (ifTable->dwNumEntries > 0)
{
for(int i=0;i<ifTable->dwNumEntries;i++)
{
pMibIfRow->dwIndex=ifTable->table.dwIndex;
if ((dwRetVal = GetIfEntry(pMibIfRow)) == NO_ERROR)
{
printf("Description: %s\n", pMibIfRow->bDescr);
if(pMibIfRow->dwInUcastPkts)//ПРОВЕРКА, Т.К. ЕСЛИ ПОПАДЕТСЯ loopback, ТО
//ТАМ МОЖЕТ ОКАЗАТЬСЯ 0, СЛЕДОВАТЕЛЬНО БУДЕТ ERROR
{
printf("Packets in: %d\n", pMibIfRow->dwInUcastPkts + pMibIfRow->dwInErrors);
printf("Octets in: %d\n", pMibIfRow->dwInOctets);
printf("Average size of a packets: %d\n", (int)(pMibIfRow->dwInOctets/(pMibIfRow->dwInUcastPkts + pMibIfRow->dwInErrors)));
}
}
else
{
printf("GetIfEntry failed. Interface number %d: \n", i);
}
printf("\n");
}
}
return 0;
}
Как посчитать сколько отправленно сам думаю догадаешься.
ЗЫ Про размер пакетов - размер не фиксирован, следовательно их размер усреднен. Поэтому в выводе добавил слово "Average".