Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
15-1380832202
Юрий
2013-10-04 00:30
2014.03.23
С днем рождения ! 4 октября 2013 пятница


15-1380974929
uw
2013-10-05 16:08
2014.03.23
Контроллер и Ethernet


2-1370372241
oliksin
2013-06-04 22:57
2014.03.23
Помогите разобраться с программой. Строки.


15-1380700463
ПЛОВ
2013-10-02 11:54
2014.03.23
вопрос по событиям


2-1370793552
Кристина
2013-06-09 19:59
2014.03.23
Помогите пожалуйста решить задачу! Никак не получается сделать(





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский