Форум: "Сети";
Текущий архив: 2014.03.23;
Скачать: [xml.tar.bz2];
ВнизWinSocket / Сокеты / RAW Socket - паралельное чтение Найти похожие ветки
← →
bwwebm (2010-04-19 14:04) [0]Возможно в API сокетов "параллельное чтение сокета" - называется по другому, если что поправьте.
Никак не могу разобраться, в том числе и понять что именно нужно применять. Для начала постановка задачи: есть сервер и приложение, сервер удаленный, а приложение находится на локальной машине. Исходников нет, но известно что приложение и клиент обмениваются пакетами. Необходимо параллельно получать в свою программу то, что шлет сервер - клиенту в чистом виде. Известно что сервер устанавливает с клиентом соединение типа STREAM и шлет непрерывно пакеты фиксированного размера? или почти непрерывно.
Вот, в общем то полноценный кусок кода, которым я пытаюсь запараллелить соединение:
...
uses ScktComp, winsock;
type RRecvData = record
Socket: TSocket;
buf: array [0..254] of Char;
buf_size: Integer;
recv_len: Integer;
th_id: Cardinal;
th_handle: Integer;
th_stop: Boolean;
hook: Boolean;
end;
PRecvData = ^RRecvData;
var
hParalell: TSocket;
paralell_recv: RRecvData;
WSA: WSAData;
procedure recv_data(wParam: Pointer);
var
Addr_in: sockaddr_in;
Addr_size: Integer;
begin
if wParam = nil then
EndThread(0);
FillChar(Addr_in,SizeOf(sockaddr_in),0);
Addr_in.sin_family:= AF_INET;
Addr_in.sin_addr.s_addr := inet_addr(PChar("0.0.0.0"));
Addr_in.sin_port := HToNS(0);
Addr_size:=SizeOf(Addr_in);
repeat
PRecvData(wParam)^.recv_len:=recvfrom(PRecvData(wParam)^.Socket, PRecvData(wParam)^.buf, PRecvData(wParam)^.buf_size, 0, Addr_in, Addr_size)
until (PRecvData(wParam)^.th_stop) OR (PRecvData(wParam)^.recv_len <> SizeOf(PRecvData(wParam)^.buf));
EndThread(1);
end;
procedure make_paralell;
var
Addr_in: sockaddr_in;
Addr_size: Integer;
bOptAddr: Bool;
begin
WSAStartup($202, WSA);
//замена SOCK_STREAM на SOCK_RAW - возмоно?
hParalell:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if hParalell= SOCKET_ERROR then begin
Exit;
end;
bOptAddr:=True;
if setsockopt(hParalell, SOL_SOCKET, SO_REUSEADDR, @bOptAddr, SizeOf(Bool)) <> 0 then begin
Exit;
end;
FillChar(Addr_in,SizeOf(sockaddr_in),0);
Addr_in.sin_family:= AF_INET;
Addr_in.sin_addr.s_addr := inet_addr(PChar("127.0.0.1"));
//Порт может меняться, ввел для примера
Addr_in.sin_port := HToNS(25471);
Addr_size:=SizeOf(Addr_in);
if bind(hParalell, Addr_in, Addr_size) = SOCKET_ERROR then begin
closesocket(hSocket);
Exit;
end;
paralell_recv.Socket:=hParalell;
paralell_recv.buf_size:=SizeOf(paralell_recv.buf);
paralell_recv.th_stop:=False;
paralell_recv.hook:=True;
sock_recv.th_handle:=BeginThread(nil, 0, @recv_data, PRecvData(@paralell_recv), 0, paralell_recv.th_id);
end;
← →
Сергей М. © (2010-04-19 14:17) [1]Цель какая ?
Ну получил ты, предположим, то что хотел.
Что дальше с этим добром делать намерен ?
← →
bwwebm (2010-04-19 14:25) [2]Анализировать. Требуется собственный анализ данных, т.к. исходного кода приложения-клиента нет, а доп. аналитика требуется.
← →
Сергей М. © (2010-04-19 14:28) [3]
> bwwebm (19.04.10 14:25) [2]
Для оффлайн-анализа вовсе не обязательно изобретать новый велосипед - вполне достаточно готовых программ-снифферов, протоколирующих сетевую активность приложений.
← →
bwwebm (2010-04-19 14:51) [4]Ознакомившись с информацией на MSDN:
- msdn.microsoft.com/en-us/library/ms738545(v=VS.85).aspx
и еще
- msdn.microsoft.com/en-us/library/ms740548%28VS.85%29.aspx
почитав electro-2006.narod.ru/text/stati/snifer.html и попробовав, разве что я не устанавливал WinPCap, а данный пример без него не работоспособен.
проглядев форумы, примеры порт - сканеров, клиент серверных многопоточных приложений, которые по сути уже реализованы в ClientSocket и ServerSocket компонентах Delphi, я не смог найти более менее вразумительного ответа.
Возможно нужно еще немного уточнить мой вопрос: имеем соединение на локальной машине на свободном порту, необходимо запустить приложение, которое смогло бы данные на указанном порту получать параллельно.
← →
bwwebm (2010-04-19 15:00) [5]И я чуть ли не забыл главного, очень хочется разобраться в данном вопросе, а не использовать многофункциональное приложение как переходник, между получением данных и их обработкой, так и не разобравшись в работе сокетов.
← →
NoRTeN (2010-04-19 16:01) [6]Я решал эту проблему так:
var
Data:TWSAData;
Sock:TSocket;
Adrr:TSockAddr;
ret:integer;
arg:u_long;
RB:integer;
buf: array [0..64000] of Byte;
I: Integer;
str,strIP:string;
AdrIP:AnsiString;
flag:Boolean;
begin
WSAStartup($0202,Data); //Инициализ. библиатеку 2.2
Sock:=socket(AF_INET, SOCK_RAW, IPPROTO_IP);//Самый низкий уровень IP
AdrIP:=AnsiString("IP адресс какой будим читать");
FillChar(Adrr, sizeof(Adrr), 0);
Adrr.sin_family:=AF_INET;
Adrr.sin_addr.S_addr:=inet_addr(PAnsiChar(AdrIP));
ret:=Bind(Sock,Adrr,sizeof(Adrr));
arg:=1;
IOCTLsocket(Sock,SIO_RECVALL, arg); //переводим сокет в режим чтения
// обсалютно всей информации поступающий на сетивую карту
//Надо создать константу тсандартной ее нет
//const
//SIO_RECVALL=$98000001;
// Теперь в бесконечном цикли читаем то-что приходит на наш адресс
while True do
begin
//проверяем есть ли что-нибудь в буфере
IOCTLSocket(Sock,FIONREAD,arg);
if arg>0 then
begin
//Читаем пришеждший пакет
ReedByte:=Recv(Sock,buf,sizeof(buf),0);
IPT:=@buf;
// Synchronize(Form1.GetPacket); тут можно вставить обработчик пакета
sleep(10) ;
end;
if CmdF=1 then
begin
CmdF:=0;
exit;
end;
end;
end;
// Я рекомидую это запихивать в отдельный поток, чтобы главная форма не
//зависала. При необходимости могу придоставить полный исходник
← →
bwwebm (2010-04-19 16:05) [7]
> Я решал эту проблему так:
...
Нет спасибо, этого примера достаточно, я пока поэкспериментирую, естественно вопросы задам.
← →
bwwebm (2010-04-19 17:00) [8]При вызове bind() ф-ия возвращает -1, а WSAGetLastError = WSAEACCES (10013).
Я для теста запустил отдельно програмулину в которой на СокСервере и СокКлиенте реализовал постоянную отправку от сервера к клиенту данных.
Соответственно в Delphi запускаю слушатель, но bind() не проходит, не на 127.0.0.1 не на адрес машины в сети.
Сразу возник еще вопрос, в данном примере не указывается порт, я так понимаю что для уровня протокола IP порта еще не существует, будут ли сложности с реализацией фильтра для трафика на известном порту?
← →
NoRTeN (2010-04-19 17:52) [9]Порты существуют на более высоком уровне, например TCP UDP. На уровне IP мы получаем IP пакет в который входит заголовок IP и поле данных IP. В поле данных IP пакета размещается заголовок внутреннего протокола, например TCP или UDP, а также его поле данных. И только уже в поле данных этого пакета возможно находяться интересующие данные. А вполне возможно там находиться еще один протокол.
Контролировать пакет с заданным портом просто. В заголовке IP пакета присутсвует поля отвечающие за тип внутреннего протокола. Для TCP это 6 для UDP это 17 и для ICMP это 1. Далее после анализа нажного протокола залезаем во внутреней протокл и смотрим его заголовок. В заголовках TCP и UDP присутсвует такое поле как порт, его и контралируем, тока нужно помнить что порт там находиться в защифрованном виде.
Прежде чем заниматьсярасшифровкой я рекоминдую ознакомиться с протоколом IP, TCP и UDP самые основные протоколы. Там особо слоджных моментов на это дело уйдет не много времяни.
Теперь что касается Bind. Тут несколько варинтов
1 Может быть например у вас Windows 7
2 Ошибка в создании сокета или заполнения структуры TSockAdr
На всякий случай можно заменить строчку с указанием адреса на такую
//Adrr.sin_addr.S_addr:=inet_addr("192.168.0.3");
//"192.168.0.3" это адрес той машины на которой запущен снифер.
//Естественно в вашем случаи он будет другим
← →
bwwebm (2010-04-22 13:44) [10]Возникновение ошибки WSAEACCES было вызвано тем, что запуск был без прав Администратора.
Кстати код очень помог, особенно понять что нужно для реализации, т.е. спасибо.
Теперь есть еще одна проблема. Она в общем то выходит за рамки данного топика, но все равно: перехват пакетов работает замечательно, до определенного момента, при включении программы, пакеты которой необходимо перехватить, ее система защиты... в общем я предполагаю что она перехватывает recv() wsock32.dll и вставляет свой обработчик, который пропускает данные передаваемые на порты используемые программой.
Кстати, у меня установлен KIS, и своим пакет-сканером он обнаруживает активность TCP трафика на порте используемом программой.
Я делаю вывод, что проще реализовать дубликат данной ф-ии самостоятельно... но как это сделать пока не нашел.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2014.03.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.002 c