Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.04.2010, 14:54   #1
bwwebm
 
Регистрация: 19.04.2010
Сообщений: 7
По умолчанию Windows Sockets / Сокеты / RAW Sockets

Никак не могу разобраться, а в том числе и понять что именно нужно применять. Для начала постановка задачи: есть сервер и приложение, сервер удаленный, а приложение находится на локальной машине. Исходников нет, но известно что приложение и клиент обмениваются пакетами. Необходимо параллельно получать в свою программу то, что шлет сервер - клиенту в чистом виде. Известно что сервер устанавливает с клиентом соединение типа 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
    ShowMessage('opt error');
    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;
bwwebm вне форума Ответить с цитированием
Старый 19.04.2010, 18:24   #2
profi
Участник клуба Подтвердите свой е-майл
 
Регистрация: 19.11.2007
Сообщений: 1,022
По умолчанию

Могу ошибаться, но по моему в Windows поддержка RAW-сокетов сделанно не полноценно, так что прийдется использовать: IPPROTO_TCP или IPPROTO_UDP.
profi вне форума Ответить с цитированием
Старый 22.04.2010, 13:51   #3
bwwebm
 
Регистрация: 19.04.2010
Сообщений: 7
По умолчанию

Цитата:
Сообщение от profi Посмотреть сообщение
Могу ошибаться, но по моему в Windows поддержка RAW-сокетов сделанно не полноценно, так что прийдется использовать: IPPROTO_TCP или IPPROTO_UDP.

Ошибаетесь, вот как инициализировать RAW сокет:
Код:
const
  SIO_RCVALL = $98000001;
  WSA_VER = $202;
...
function TIPHandler.Init: Integer;
begin
  Result:=WSAStartup(WSA_VER, WSA);
  if Result <> NOERROR then
    Exit;
  hSocket:=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  if hSocket = INVALID_SOCKET then begin
    Close; //метод класса TIPHandler, закрывающий соединение
    Exit;
  end;
  FillChar(Addr_in, SizeOf(sockaddr_in), 0);
  Addr_in.sin_family:= AF_INET;
  Addr_in.sin_addr.s_addr := inet_addr(SocketHost);
  if bind(hSocket, Addr_in, SizeOf(sockaddr_in)) <> 0 then begin
    Close;
    Exit;
  end;
  Switch:=1;
  //Переход в неразборчивый режим
  if ioctlsocket(hSocket, SIO_RCVALL, Switch) <> 0 then begin
    Close;
    Exit;
  end;
  Result:=hSocket;
end;

Последний раз редактировалось bwwebm; 22.04.2010 в 13:56.
bwwebm вне форума Ответить с цитированием
Старый 22.04.2010, 14:04   #4
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,742
По умолчанию

Код:
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;
если неизвестна структура пакетов, то откуда это вы взяли?
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 23.04.2010, 09:53   #5
bwwebm
 
Регистрация: 19.04.2010
Сообщений: 7
По умолчанию

Эта запись не имеет отношения к чтению пакета, просто для удобства написал когда начинал разбираться.
bwwebm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Qt, Threads, Sockets... i-cpp Qt и кроссплатформенное программирование С/С++ 1 30.03.2010 02:10
System.Net и System.Net.Sockets Adwenturer Общие вопросы .NET 4 08.02.2010 22:08
Декодирование 48 битного RAW формата Rezet Мультимедиа в Delphi 5 23.01.2009 18:21
raw пакет spoool Работа с сетью в Delphi 1 02.12.2008 08:43