Форум: "Сети";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
ВнизПомогите с сокетом Найти похожие ветки
← →
V@LER@N © (2004-04-26 15:39) [0]Всем доброго времени суток. Есть такая трабла: как смастерить програмулину, которая, работая в ЛАНе (5 компов) на одной из машин, могла бы получать инфу, к-рая приходит на эту машину с других. Пытался писАть на стандартных сокетах - ничего не получилось:(. Смущает такая вещь как "порт" - каков его смысл и где взять его значение я так и не расчехлил. Пробовал переделать один из снифферов (пример Verg"a) - запутался еще сильнее. Сам сниффер у меня работать не стал. Там было сказано, что это только пример, а не рабочая прога, но хоть какие-то признаки жизни он подавать должен был...
← →
Digitman © (2004-04-26 18:09) [1]
> Пытался писАть на стандартных сокетах
что есть "стандартных сокетах" ?
> Сам сниффер у меня работать не с
программисту, себя таковым считающему, известно такое понятие как "отладка программы" ... Делфи-программисту тем паче известно, что среда Делфи содержит встроенный отладчик , который предназначен для использования отнюдь не Пушкиным А.С.
← →
Polevi © (2004-04-27 08:18) [2]снифер он пишет, ты бы еще с TDI начал чтоли
← →
имя (2004-04-27 08:21) [3]Удалено модератором
← →
V@LER@N © (2004-04-27 17:29) [4]Удалено модератором
Примечание: Оффтоп...
← →
Digitman © (2004-04-27 17:42) [5]Удалено модератором
Примечание: Оффтоп...
← →
VMcL © (2004-04-27 17:46) [6]Удалено модератором
Примечание: Все что ниже удалено - оффтоп...
← →
Digitman © (2004-04-27 17:48) [7]Удалено модератором
← →
Digitman © (2004-04-27 18:00) [8]Удалено модератором
← →
V@LER@N © (2004-04-27 18:14) [9]Удалено модератором
← →
Digitman © (2004-04-27 18:21) [10]Удалено модератором
← →
Piter © (2004-04-27 19:25) [11]Удалено модератором
← →
Verg © (2004-04-27 20:56) [12]
> Заново писать не буду, так как сижу в инет-кафе, а по памяти
> написать не смогу... Он у меня зависает на вызове recv.
> Почему?
По памяти, насколько я помню, люди которые на самом деле решили его попробовать обычно спрашивали: "чему равна константа SIO_RCVALL" и кто такой модуль mstсpip, winsock2? Просто интересно, почему у тебя таких вопросов не возникает?
Кстати, ты знаешь, что в сетях Microsoft Windows информация может передаваться не только с применением IP-базирующихся протоколов?
SOCK_RAW, тем временем может принимать (передавать) ТОЛЬКО IP датаграммы.
← →
Verg © (2004-04-27 21:25) [13]В качестве развлечения (появился часок другой св. вр.), предлагаю продолжить тему консольных сниферов, т.е. модорнизацию их уже на более кокретные, полезные цели. Считаю себя вправе выбрать тему для такого развлечения и начинаю с метафоры.
Пусть нам хочется узнать интенсивность потребления TCP - трафика некоего хоста в нашей (а в слчаях транзитных сетей возможно и не нашей) сети. Т.е. надо узнать с какой интенсивностью некий хост (Target IP) принимает TCP трафик. Для чего? Ну, например, для того, чтобы предсказать его на будущее и указать, например, на черезмерность. Но главное - иллюстрация работы не столько даже SOCK_RAW, сколько понимание что и где лежит в IP пакетах вместе с надстроенным протоколом верхнего уровня (в данном случае - TCP)
К тому же давайте учтем, что при некоторых условиях пиковая скорость поступления TCP/IP потока (сегментов) очень высока. ..... я думаю, что нужно бы оценить справляется наш "счетчик" или нет.
Итак, первое, что приходит в голову - это необходимость создать модуль, который описывал структуры данных приходящих к нам с SOCK_RAW.
Итак, назовем его IpUtils.pasunit IPUtils;
interface
uses Windows, WinSock2;
const
IP_MAXPACKET = high(word);
type
// IP header
PIPHeader = ^TIPHeader;
TIPHeader = packed record
verlen : byte; // версия и длина заголовка
tos : byte; // тип сервиса
length : word; // длина всего пакета
id : word; // Id
offset : word; // флаги и смещения
ttl : byte; // время жизни
protocol : byte; // протокол
xsum : word; // контрольная сумма
src : TInAddr; // IP-адрес отправителя
dst : TInAddr; // IP-адрес назначения
end;
// TCP Header
TTCPHeader = packed record
Source: word; //Source Port
Destination: word; //Destination Port
Seq: ulong; // порядковый номер передаваемого октета
Ack: ulong; // порядковый номер принятого октета
Rsvd0_Off: byte; //Смещение до начала данных
Flags_Rsvd1: byte; //флаги
Window: word; // Размер окна
Checksum: word;
UrgPoint: word;
end;
PTCPHeader = ^TTCPHeader;
//Флаги TCP (TTCPHeader.Flags_Rsvd1)
const
TCP_FLAG_FIN = $01;
TCP_FLAG_SYN = $02;
TCP_FLAG_RST = $04;
TCP_FLAG_PSH = $08;
TCP_FLAG_ACK = $10;
TCP_FLAG_URG = $20;
function net_checksum( var data; len : word):word;
function net_chksum_add( S1, S2 : word ) : word;
function PHCheckSumm(Src, Dst : TInAddr;
Proto: byte;
Len : word):word;
implementation
uses SysUtils;
type
// Псевдозаголовок
TPSUHeader = packed record
Src: TInAddr;
Dst: TInAddr;
Zero: byte;
Protocol: byte;
Length: word;
end;
PPSUHeader = ^TPSUHeader;
function net_checksum( var data; len : word):word;
var
Sum : ulong;
Dp : PWORD;
Words : integer;
begin
Sum := 0;
Dp := PWORD(@Data);
for Words := 1 to Len shr 1 do
begin
sum := sum + dp^;
inc(Dp);
end;
if odd(len) then
Sum := Sum + ord(pchar(Dp)^);
Sum := (Sum and $FFFF) + LongRec(Sum).Hi;
Result:= LongRec(sum).Lo + LongRec(Sum).Hi;
if Result <> $FFFF then
Result := not Result;
end;
function net_chksum_add( S1, S2 : word ) : word;
var
Sum : ulong;
begin
Sum := ulong(s1) + ulong(s2);
result := Sum;
if LongRec(Sum).Hi <> 0 then
Sum := Result + 1
else
Sum := Result;
if (Sum = 0) and ((S1 or S2) <> 0) then
result := $FFFF
else
result := Sum;
end;
function PHCheckSumm(Src, Dst : TInAddr;
Proto: byte;
Len : word):word;
var pH : TPSUHeader;
begin
pH.Src := src;
pH.Dst := dst;
pH.Protocol := Proto;
pH.Zero := 0;
pH.Length := htons(Len);
result := net_checksum(pH, sizeof(pH));
end;
end.
Думаю, что будет достаточно для модуля такого предназначения...
to be continued...
← →
Verg © (2004-04-27 21:36) [14]Теперь, стоит вспонить, что SOCK_RAW может работать в режиме "сковзного приема" (SIO_RCVALL) только с локальным адресом совпадающим с IP адресом какого-то одного, конкретного, реально физически существующего сетевого интерфейса (сетевого адаптера). Т.е. такому сокету нельзя назначить локальный адрес типа INADDR_ANY (0.0.0.0) или INADDR_LOOPBACK (127.0.0.1).
Т.о., если мы решили "наблюдать" за IP трафиком идущим в сторону конкретоного адрес, то мы должы из, в общем случае, множества сетевых адаптеров на нашем компе определить такой, который быдет в состоянии принимать (слышать) пакеты адресованные Target IP. Я предпочитаю для этого пользоваться замечательной библиотекой iphlpapi.dll, поэтому надо создать минимальный интерфейсный модуль для использования ее возможностями.unit IPHelper;
interface
uses Windows;
const
MAX_INTERFACE_NAME_LEN = 256;
MAX_TRANSPORT_NAME_LEN = 40;
MAX_MEDIA_NAME = 16;
MAX_PORT_NAME = 16;
MAX_DEVICE_NAME = 128;
MAX_PHONE_NUMBER_LEN = 128;
MAX_DEVICETYPE_NAME = 16;
MAXLEN_IFDESCR = 256;
MAXLEN_PHYSADDR = 8;
type
TIPAddr = ULONG; // An IP address.
TIPMask = ULONG; // An IP subnet mask.
TIP_STATUS = ULONG; // Status code returned from IP APIs.
TMIB_IFROW = record
wszName : array[0..MAX_INTERFACE_NAME_LEN-1] of widechar;
dwIndex,
dwType,
dwMtu,
dwSpeed,
dwPhysAddrLen : DWORD;
bPhysAddr : array[0..MAXLEN_PHYSADDR-1] of BYTE;
dwAdminStatus,
dwOperStatus,
dwLastChange,
dwInOctets,
dwInUcastPkts,
dwInNUcastPkts,
dwInDiscards,
dwInErrors,
dwInUnknownProtos,
dwOutOctets,
dwOutUcastPkts,
dwOutNUcastPkts,
dwOutDiscards,
dwOutErrors,
dwOutQLen,
dwDescrLen : DWORD;
bDescr : array[0..MAXLEN_IFDESCR-1] of BYTE;
end;
PMIB_IFROW = ^TMIB_IFROW;
const
MIB_IF_TYPE_OTHER = 1;
MIB_IF_TYPE_ETHERNET = 6;
MIB_IF_TYPE_TOKENRING = 9;
MIB_IF_TYPE_FDDI = 15;
MIB_IF_TYPE_PPP = 23;
MIB_IF_TYPE_LOOPBACK = 24;
MIB_IF_TYPE_SLIP = 28;
MIB_IF_ADMIN_STATUS_UP = 1;
MIB_IF_ADMIN_STATUS_DOWN = 2;
MIB_IF_ADMIN_STATUS_TESTING = 3;
MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0;
MIB_IF_OPER_STATUS_UNREACHABLE = 1;
MIB_IF_OPER_STATUS_DISCONNECTED = 2;
MIB_IF_OPER_STATUS_CONNECTING = 3;
MIB_IF_OPER_STATUS_CONNECTED = 4;
MIB_IF_OPER_STATUS_OPERATIONAL = 5;
type
TMIB_IFTABLE = record
dwNumEntries : DWORD;
table : array[0..0] of TMIB_IFROW;
end;
PMIB_IFTABLE = ^TMIB_IFTABLE;
TMIB_IPADDRROW = record
dwAddr,
dwIndex,
dwMask,
dwBCastAddr,
dwReasmSize : DWORD;
unused1,
unused2 : WORD;
end;
PMIB_IPADDRROW = ^TMIB_IPADDRROW;
TMIB_IPADDRTABLE = record
dwNumEntries : DWORD;
table : array[0..0] of TMIB_IPADDRROW;
end;
PMIB_IPADDRTABLE= ^TMIB_IPADDRTABLE;
TMIB_IPFORWARDROW = record
dwForwardDest : DWORD;
dwForwardMask : DWORD;
dwForwardPolicy : DWORD;
dwForwardNextHop : DWORD;
dwForwardIfIndex : DWORD;
dwForwardType : DWORD;
dwForwardProto : DWORD;
dwForwardAge : DWORD;
dwForwardNextHopAS : DWORD;
dwForwardMetric1 : DWORD;
dwForwardMetric2 : DWORD;
dwForwardMetric3 : DWORD;
dwForwardMetric4 : DWORD;
dwForwardMetric5 : DWORD;
end;
PMIB_IPFORWARDROW = ^TMIB_IPFORWARDROW;
const
MIB_IPROUTE_TYPE_OTHER = 1;
MIB_IPROUTE_TYPE_INVALID = 2;
MIB_IPROUTE_TYPE_DIRECT = 3;
MIB_IPROUTE_TYPE_INDIRECT= 4;
type
TMIB_IPFORWARDTABLE = record
dwNumEntries : DWORD;
table : array[0..0] of TMIB_IPFORWARDROW;
end;
PMIB_IPFORWARDTABLE = ^TMIB_IPFORWARDTABLE;
function GetIfTable(pIfTable : PMIB_IFTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;
function GetIpAddrTable(pIpAddrTable : PMIB_IPADDRTABLE; var pdwSize : ULONG; bOrder : BOOL): DWORD; stdcall;
function SendARP(DestIP:DWORD;SrcIP:DWORD; var pMacAddr; var PhyAddrLen:DWORD):DWORD;stdcall;
function SetIfEntry(pIfRow : PMIB_IFROW // specifies interface and status
): DWORD; stdcall;
function GetIpForwardTable(
pIpForwardTable : PMIB_IPFORWARDTABLE; // buffer for routing table
var pdwSize : ULONG; // size of buffer
bOrder : BOOL // sort the table
): DWORD; stdcall;
function GetBestInterface(
dwDestAddr : DWORD; // destination IP address
var pdwBestIfIndex : DWORD // index of interface with the best route
) : DWORD; stdcall;
function GetIfEntry(var pIfRow : TMIB_IFROW ): DWORD; stdcall; // pointer to interface entry
function NotifyRouteChange(var Handle : THandle; var overlapped : TOverlapped):DWORD; stdcall;
implementation
function GetIfTable; external "IPHLPAPI.DLL";
function GetIpAddrTable; external "IPHLPAPI.DLL";
function SendARP; external "IPHLPAPI.DLL";
function SetIfEntry; external "IPHLPAPI.DLL";
function GetIpForwardTable;external "IPHLPAPI.DLL";
function GetBestInterface; external "IPHLPAPI.DLL";
function GetIfEntry; external "IPHLPAPI.DLL";
function NotifyRouteChange;external "IPHLPAPI.DLL";
end.
← →
Verg © (2004-04-27 21:48) [15]Так, теперя, я думаю, будет полезным иметь возможность считать не просто интенсивность входящего TCP/IP трафика, а с какого-то конкретого,заданного порта. Хм... Представилось, как некий комп в итрасети (бынальные 192.168......) качает из интернента через прокси (другого пути в интернет у него просто нет). Значит, задав известный порт прокси (например, 3128) мы можем селектировать именно такой трафик....
Впрочем, давайте условимся, что если в качесве порта будет задано значение 0 (ноль), то мы будем считать трафик с любого порта источника без разбору.
← →
Verg © (2004-04-27 21:56) [16]Проблемка чисто математического плана: если наш проц достаточно быстр и быстр на столько, что время обработки датаграммы почти не зависит от ее размера, то получится по-моему обман, если мы будем усреднять скорость обработки поступающей информации, складывая их объем и деля на суммароне время обработки каждой в условиях множества малых пакетов.
Ну что ж, введем понятия "малой" датаграммы и не будем учитывать в расчете средней производительности датаграммы "нулевого" размера.
← →
Verg © (2004-04-27 22:03) [17]Да, чтобы пока нескучно было :) качайте Winsock2.pas, с молчаливого разрешения (я надеюсь) Alex Konshin-а :)
http://home.earthlink.net/~akonshin/files/ws2rev4a.zip
И еще модульunit mstcpip;
interface
uses Winsock2;
type
_tcp_keepalive = packed record
onoff : u_long;
keepalivetime : u_long;
keepaliveinterval : u_long;
end;
const
// New WSAIoctl Options
SIO_RCVALL = IOC_IN or IOC_VENDOR or 1;
SIO_RCVALL_MCAST = IOC_IN or IOC_VENDOR or 2;
SIO_RCVALL_IGMPMCAST = IOC_IN or IOC_VENDOR or 3;
SIO_KEEPALIVE_VALS = IOC_IN or IOC_VENDOR or 4;
SIO_ABSORB_RTRALERT = IOC_IN or IOC_VENDOR or 5;
SIO_UCAST_IF = IOC_IN or IOC_VENDOR or 6;
SIO_LIMIT_BROADCASTS = IOC_IN or IOC_VENDOR or 7;
SIO_INDEX_BIND = IOC_IN or IOC_VENDOR or 8;
SIO_INDEX_MCASTIF = IOC_IN or IOC_VENDOR or 9;
SIO_INDEX_ADD_MCAST = IOC_IN or IOC_VENDOR or 10;
SIO_INDEX_DEL_MCAST = IOC_IN or IOC_VENDOR or 11;
// Values for use with SIO_RCVALL* options
RCVALL_OFF = 0;
RCVALL_ON = 1;
RCVALL_SOCKETLEVELONLY = 2;
implementation
end.
← →
Verg © (2004-04-27 22:36) [18]Вот, что получилось. Это, конечно, немного тяжеловато, но оптимизацию предлагаю сделать самим заинтересованным.
program Console;
{$APPTYPE CONSOLE}
{$DEFINE REALTIME}
{$DEFINE CHECKSUMM}
uses
Windows,
SysUtils,
WinSock2 in "WinSock2.pas",
mstcpip in "mstcpip.pas",
IPUtils in "IPUtils.pas",
IPHelper in "IPHelper.pas";
const
MEGASIZE = (1024*1024);
MIN_SPEED_SIZE = 500;
var
WSAData : TWSAData;
Sa : TSockAddrIn;
Rcvd : integer;
RS : TSocket;
flag : DWORD;
Buffer : array[0..IP_MAXPACKET-1] of byte;
Iph : TIpHeader absolute Buffer;
HeaderLen : DWORD;
IPData : pchar;
DstIP : DWORD;
DstPort : WORD;
Trafic0,
Trafic: Int64;
Tmv : TTimeVal;
StTime : DWORD;
DGSpeedTimer, DGSpeedTimer2 : Int64;
DGSpeedTimeSumm,
DGSpeedCounter : Int64;
FreqAvail : boolean;
Freq : Int64;
StartTime : TDateTime;
procedure SaveData;
var Fn : string;
F : text;
begin
Fn := ExtractFilePath(ParamStr(0))+IntToStr(DstIp)+IntToStr(DstPort)+".dat";
Assign(F, Fn);
rewrite(F);
WriteLn(F, StartTime, " ", Trafic);
Close(F);
end;
procedure LoadData;
var Fn : string;
F : text;
begin
Fn := ExtractFilePath(ParamStr(0))+IntToStr(DstIp)+IntToStr(DstPort)+".dat";
Assign(F, Fn);
if FileExists(Fn) then
begin
reset(F);
ReadLn(F, StartTime, Trafic);
Close(F);
end else
begin
StartTime := now;
Trafic := 0;
end;
end;
function CheckIP( DstIP : DWORD ): boolean;
begin
result := true;
if (DstIp = htonl(INADDR_ANY)) or
(DstIp = htonl(INADDR_LOOPBACK)) or
(DstIp = htonl(INADDR_NONE)) then
result := false;
end;
function CtrlHandler(dwCtrlType : DWORD):BOOL; stdcall;
var S : TSocket;
begin
if RS<>INVALID_SOCKET then
begin
S:= RS;
RS := INVALID_SOCKET;
CloseSocket(S);
end;
result := BOOL(true);
end;
function ToOem(const S : string):string;
begin
Result := S;
if Result<>"" then
CharToOemBuff(pchar(Result), pchar(Result), length(Result));
end;
function ProcessDGSpeed : double;
begin
Result := -1;
if not FreqAvail then
exit;
if DGSpeedCounter = 0 then
DGSpeedCounter := 1;
Result := ( DGSpeedCounter / (DGSpeedTimeSumm / Freq) ) / MEGASIZE;
if DGSpeedCounter > 100*MEGASIZE then
begin
DGSpeedTimeSumm := 0;
DGSpeedCounter := 0;
end;
end;
function ProcessTrafic:boolean;
var MbSec : double;
begin
Result := false;
if Trafic0 > 0 then
begin
inc(Trafic, Trafic0);
Trafic0 := 0;
MbSec := Trafic/((Now - StartTime)*MEGASIZE);
Write(ToOem("Трф. "+inet_ntoa(TInAddr(DstIP))+
" с порта "+IntToStr(ntohs(DstPort))+" = "),
Trafic, #9,
"(", MbSec:3:1, toOem(" МБ/сут)"));
if FreqAvail then
WriteLn(" ", ProcessDGSpeed:3:1, ToOem("МБ/с"))
else
WriteLn;
SaveData;
Result := true;
end;
end;
procedure PrintErr(Err : DWORD; Wt : boolean);
begin
Writeln(ToOem(SysErrorMessage(Err)));
if Wt then ReadLn;
end;
procedure ExitErr;
begin
if (WSAGetLastError<>NO_ERROR) and
(WSAGetLastError<>WSAENOTSOCK) and
(WSAGetLastError<>WSAEINTR) then
PrintErr(WSAGetLastError, true)
else
if ProcessTrafic then
ReadLn;
if Rs<> INVALID_SOCKET then
CloseSocket(RS);
if WSAData.wVersion <> 0 then
WSACleanup;
halt(0);
end;
function checksocket(Ret : integer):integer;
begin
Result := Ret;
if Result = SOCKET_ERROR then
begin
if WSAGetLastError <> WSAETIMEDOUT then
ExitErr
else
result :=0;
end;
end;
function InterfaceTo( DstIp : DWORD; var IntIP : DWORD) : integer;
var Table : PMIB_IPADDRTABLE;
TableSize : ulong;
Bi : DWORD;
I : integer;
Res : DWORD;
procedure CheckIPHLP(R: DWORD);
begin
if R<>NO_ERROR then
begin
WSASetLastError(R);
ExitErr;
end;
end;
begin
Result := -1;
IntIp := INADDR_NONE;
CheckIPHLP(GetBestInterface(DstIp, Bi) );
TableSize := 0;
Res := GetIpAddrTable(nil, TableSize, false);
if TableSize <> 0 then
begin
GetMem(Table, TableSize);
try
CheckIPHLP(GetIpAddrTable(Table, TableSize, false));
for I:= 0 to Table^.dwNumEntries-1 do
if Table^.table[I].dwIndex = Bi then
begin
Result := 0;
IntIP := Table^.table[I].dwAddr;
if IntIP = htonl(INADDR_LOOPBACK) then
begin
// Получлось, что задан собственно один из адресов нашего хоста
result := 1;
IntIp := DstIP;
Break;
end;
if (IntIP and Table^.table[I].dwMask) =
(DstIp and Table^.table[I].dwMask) then
begin
Result := 1;
break;
end;
end;
finally
FreeMem(Table);
end;
end else
CheckIPHLP(Res);
end;
← →
Verg © (2004-04-27 22:37) [19]
procedure RealTime;
begin
if not SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS) or
not SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL) then
begin
WSASetLastError(GetLastError);
ExitErr;
end;
end;
function TCPInput(Iph: PIPHeader; TCPPacket : PTCPHeader; Size : word): boolean;
begin
Result := false;
if Size < sizeof(TTCPHeader) then exit;
if DstPort<>0 then
if TCPPacket^.Source <> DstPort then exit; //Только нужный порт
//SOCK_RAW гарантирует, что IP заголовок имеет правильную КС,
// но на все остальные уровни он плевал, поэтому придется расчитать
// КС TCP пакета самим
{$IFDEF CHECKSUMM}
if net_chksum_add(PHCheckSumm(Iph^.src, Iph^.dst, IPPROTO_TCP, Size),
net_checksum(TCPPacket^, Size)
) <> $FFFF then
exit;
{$ENDIF}
Inc(Trafic0, ntohs(Iph^.length));
Result := true;
end;
begin
Trafic := 0;
Trafic0 := 0;
SetConsoleTitle("SOCK_RAW usage demo.");
RS := INVALID_SOCKET;
if ParamCount <> 2 then
begin
Writeln("Usage: "+ExtractFileName(ParamStr(0))+" <Target IP> <Target port>");
Readln;
Exit;
end;
DstIp := inet_addr(pchar(ParamStr(1)));
if not CheckIP(DstIp) then
begin
Writeln("Invalid Target IP");
Readln;
Exit;
end;
DstPort := htons( StrToIntDef(ParamStr(2), 0) );
if WSAStartup(MAKEWORD(2, 2), WSAData)<> NO_ERROR then
ExitErr;
try
RS := socket(PF_INET, SOCK_RAW, IPPROTO_IP);
if RS = INVALID_SOCKET then
ExitErr;
try
ZeroMemory( @sa, sizeof(sa) );
sa.sin_family := AF_INET;
case InterfaceTo(DstIp, sa.sin_addr.S_addr) of
-1 : ExitErr;
0 : writeln(ToOem("Пакеты Target IP могут не приходить на наш хост."));
end;
checksocket(bind(RS, @sa, sizeof(sa)));
Tmv.tv_sec := 2;
Tmv.tv_usec := 0;
checksocket( setsockopt(RS, SOL_SOCKET, SO_RCVTIMEO,
pchar(@Tmv), sizeof(Tmv) ));
flag:= 1;
checksocket( ioctlsocket(RS, SIO_RCVALL , flag) );
Tmv.tv_sec := Tmv.tv_sec * 1000;
SetconsoleCtrlHandler(@CtrlHandler, LongBool(TRUE));
LoadData;
{$IFDEF REALTIME}
RealTime;
{$ENDIF}
StTime := GetTickCount;
DGSpeedCounter := 0;
FreqAvail :=QueryPerformanceFrequency(Freq);
repeat
if GetTickCount - StTime > DWORD(Tmv.tv_sec) then
Rcvd := 0
else
Rcvd := checksocket( recv(RS, Buffer, sizeof(Buffer), 0) );
if Rcvd > 0 then
begin
if FreqAvail then QueryPerformanceCounter( DGSpeedTimer );
if Iph.dst.S_addr = DstIp then // Только нужный IP
begin
HeaderLen := (Iph.verlen and $F) shl 2; // Длина IP заголовка
IPData := pchar(@Iph)+HeaderLen;
if Rcvd <> ntohs( Iph.length ) then
WriteLn("Error: IP.LENGTH mismatch!");
case Iph.protocol of
IPPROTO_TCP : if TCPInput(@Iph,
PTCPHeader( IPData ),
DWORD(Rcvd) - HeaderLen) then
StTime := GetTickCount;
end;
end;
if FreqAvail and (Rcvd > MIN_SPEED_SIZE) then
begin
QueryPerformanceCounter( DGSpeedTimer2 );
Inc(DGSpeedTimeSumm, DGSpeedTimer2 - DGSpeedTimer);
Inc(DgSpeedCounter, Rcvd);
end;
end else
begin
ProcessTrafic;
StTime := GetTickCount;
end;
until false;
finally
closesocket(RS);
end;
finally
WSACleanup;
end;
end.
← →
Rouse_ © (2004-04-27 23:05) [20]> Digitman ©
Сергей, большая просьба...
Я очень уважительно отношусь к Вашим знаниям и ни в коем случае не умаляю их, но большая просьба:
Пожалуйста, будьте более выдержанны к участникам форумов, я не могу пропускать посты с таким содержанием и приходится их удалять... :(
Я очень не хочу продолжать такую профилактику в будующем...
← →
Verg © (2004-04-27 23:28) [21]Ну вот, за приемлимое время у меня получилось:
Условия:
Win2K Pro RUS SP4 P4 1.5G 512M
За прошедшее с запуска время - потрябляемый моим адресом трафик через мой прокси - 20,6 МБ/сут. Средняя производительность счетчик в режиме REALTIME с расчетом конрольной суммы - 203 МБ/с.
Для сети 100 bps предельная производительность д.б ~12 МБ/c. Т.о. запас более чем достаточный.
Можно сделать NT-сервис с "предохранителем", например, чтобы верещала, если среднее потребление трафика превысило некоторый порог. Впрочем, наверняка это где-ниубдь, в каких-нибудь утилитах давно сделано :) в лучшем виде :))))
← →
Digitman © (2004-04-28 08:01) [22]
> Rouse_ © (27.04.04 23:05) [20]
Ok.
Приношу извинения
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.028 c