Конференция "Сети" » Отправка пакета по сети(Winsock2). [D7, WinXP]
 
  • RokWeb (16.01.10 14:29) [0]
    Здравствуйте. Есть следующая задача - необходимо отправить пакет по сети без каких либо его видоизменений(чтобы он точно соответствовал тому, что я введу например). Есть следующий код:

    function HexToDec(Str: string): Integer;
    var
     i, M: Integer;
    begin
     Result:=0;
     M:=1;
     Str:=AnsiUpperCase(Str);
     for i:=Length(Str) downto 1 do
     begin
       case Str[i] of
         '1'..'9': Result:=Result+(Ord(Str[i])-Ord('0'))*M;
         'A'..'F': Result:=Result+(Ord(Str[i])-Ord('A')+10)*M;
       end;
       M:=M shl 4;
     end;
    end;

    function PushByteMessage(MsgTxt:TStrings):TByteArray;
    var i,j:integer;
    s,buf1:string;
    Massiv:TByteArray;
    k:integer;
    b:Integer;
    Begin
     k:=0;
     for i:=0 to MsgTxt.Count do begin
       s:=MsgTxt.Strings[i];
       While s<>'' do begin
         if pos(' ',s)=0 then begin
           buf1:=s;    
           SetLength(Massiv,k+1);
           Massiv[k]:=HexToDec(buf1);  
           inc(k);
           s:='';
           break;
         end;
         buf1:=Copy(s,1,pos(' ',s)-1);
         
         SetLength(Massiv,k+1);
         Massiv[k]:=HexToDec(buf1);
         inc(k);
         s:=Copy(s,pos(' ',s)+1,length(s));
       end;
     end;
     result:=Massiv;

    End;

    //Отправка
    function SendTo(IP_Addr:string;Port:Word;SendBuff:string):boolean;
    var
     WDat: TWSAData;
     ConnectSock: TSocket;
     Addr: TSockAddr;
     MessageTxt:TByteArray;
    begin
     MessageTxt:=PushByteMessage(SendForm.MessageText.Lines);
     result:=false;
     WSAStartup(MAKEWORD(2,0), WDat);
     ConnectSock:= Socket(AF_Inet, Sock_RAW, ipproto_ip);
     if ConnectSock = invalid_socket then  begin
     ShowMessage('ConnectSock = invalid_socket');
     exit;
     end;
     fillchar(Addr,sizeof(tsockaddr),0);
     Addr.sin_family:= AF_INET;
     Addr.sin_port:=  htons(Port);
     Addr.sin_addr.S_addr := inet_addr(PChar(IP_Addr));
     if Connect(ConnectSock, @Addr,  sizeof(tsockaddr))= socket_error then begin
     ShowMessage('ConnectError');
     exit;
     end;
     if Send(ConnectSock, MessageTxt, Sizeof(MessageTxt), 0)= socket_error then begin
     ShowMessage('Send Error');
     exit;
     end;
     closesocket(ConnectSock);
     wsacleanup;
     result:=true;
    end;

    procedure TSendForm.Button2Click(Sender: TObject);
    begin

    if MessagePort.Text='' then exit;
    if MessageText.Lines.Text='' then exit;
    if MessageIP.Text='' then exit;
    if not SendTo(MessageIP.Text, StrToInt(MessagePort.text),PChar(MessageText.Lines.Text)) then Showmessage('Сообщение не было отправленно');

    end;

    Подскажите, правилен он и если нет - помогите исправить. Например:
    С данным кодом я ввожу следующее на отправку:
    1B 01 02 03 04 05 06
    Через снифер WPE Pro смотрю, что удалось отправить и там показано совсем другое - не то, что я отправлял.

    И тебе второй вопрос в, уже упомянутом снифере WPE Pro есть функция - не создавая нового сокета он отправит пакет. Хотелось бы узнать как он это делает и как это можно реализовать в Delphi(например, как узнать Socked ID и по нему отправить нужный мне пакет).

    Заранее благодарю!

    С Уважением, Алексей!
  • Сергей М. © (16.01.10 22:34) [1]

    > там показано совсем другое - не то, что я отправлял


    И что же он показывает ?
  • RokWeb (17.01.10 00:34) [2]
    Уже исправил SizeOf на Length.

    Вот в самой программе на отправку вставил:
    12 3A BC D1

    Через дебагер увидел следующее значение переменной:
    Messagetxt = (18, 58, 188, 209)

    В снифере WPE Pro увидел этот же пакет вот так:
    44 58 98 00

    Совсем запутался... как же все таки надо правильно отправлять пакет так - чтобы сервер его получал в исходном виде(чтобы он получал реально, что Я отправил, а не видоизмененный пакет)
  • Anatoly Podgoretsky © (17.01.10 02:18) [3]
    Не надо ли @MessageTxt[0]
  • BarakudaX777 (17.01.10 11:17) [4]
    MessageTxt:TByteArray;
    Это динамичееский Массив чисел.

    ЧТо даст @MessageTxt[0]?

    Может сама идея отправки не такая. Процедура отправки Send не привязанна к определенному типу. Вот и не знаю в каком виде отправлять данные.
    Просто видел снифер там прием от сервера сообщений приходит в массив чисел. Вот и отправку реализовал в таком же виде. Как приходит сообщение, в таком же виде отправляешь а до сервера доходет в другом виде.

    Может это быть связанно с кодировкой? Кажется там сервер в кодировке UTF8 работает. Представляет информацию. Вот чтот совсем запутался!
  • RokWeb (17.01.10 12:34) [5]
    Дело не в сервере... Опишу поподробнее ситуацию:

    Пишется некая программа для игры, её суть - перехватить входящий пакет, проанализировать и отправить исходящий пакет на сервер. Для "теста" отправки пакета - я перехватываю НОРМАЛЬНЫЙ пакет игры:
    7B 00 00 91 F1 07 00 2A 39 D1 CA D3 CF C0 C5 CC 20 D1 C5 D0 C5 C1 D0 CE 20 2A 34 43 52 49 54 49 43 41 4C 4B 45 59 2E 55 43 4F 5A 2E 52 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00



    Пытаюсь просто отправить его же через мою программу(предварительно включил сниффер WPE pro, чтобы посмотреть, что же на самом деле отправляет моя программа) и вижу, что отправляет моя программа совсем другой пакет:
    F8 85 98 00 68 AB 98 00 EC F5 12 00 78 BB 47 00 3C F9 12 00 C6 BB 47 00 EC F5 12 00 DC AE 98 00 68 AB 98 00 A0 85 98 00 58 B5 98 00 D8 B6 98 00 AC 5B 98 00 BC 91 98 00 A8 91 98 00 FC F5 12 00 20 68 44 00 DC AE 98 00 DC AE 98 00 0C F6 12 00 C0 CB 43 00 6C 8C 98 00 DC AE 98 00 20 F6 12 00 27 CD 43 00 90 0E 3C 00 94 F7 12 00 DC AE 98 00 4C F7 12 00 F2 65 44 00 90 0E 3C



    Почему же отправляет не то, что нужно?
  • Сергей М. © (17.01.10 17:43) [6]

    > ЧТо даст @MessageTxt[0]?


    Даст требуемый результат.
  • RokWeb (17.01.10 17:53) [7]
    Сделал так:
    if Send(ConnectSock, @MessageTxt[0], Length(MessageTxt), 0)= socket_error then begin



    Ошибка при компиляции:
    [Error] USend.pas(111): Constant object cannot be passed as var parameter

  • Сергей М. © (17.01.10 18:44) [8]
    И чего ?
    Ты не в состоянии понять то что говорит тебе компилятор ?
  • RokWeb (17.01.10 19:44) [9]
    Уважаемый, зачем так агрессивно? Дело в том, что данной функции я не передаю констант :).
  • Сергей М. © (17.01.10 20:09) [10]
    И чего, "неагрессивный" ты наш ?

    Ты уже в теме облажался с передачей указателя.

    Гонор свой при этом не желаешь умерить ?
  • Anatoly Podgoretsky © (17.01.10 20:26) [11]
    Видимо надо использовать указатель, типизированый или нет.
    Вообще это твоя задача посмотреть объявление функции, никто другой делать это особо не будет.
  • Сергей М. © (17.01.10 20:31) [12]

    > Anatoly Podgoretsky ©   (17.01.10 20:26) [11]


    А ему по барабану.
    Ему здесь обязаны.
  • Anatoly Podgoretsky © (17.01.10 21:11) [13]
    > Сергей М.  (17.01.2010 20:31:12)  [12]

    А нам не хочется. Оно нам нужно?
  • Сергей М. © (17.01.10 21:31) [14]

    > Оно нам нужно?


    Разбираться откуда взялся Winsock2 и как там объявлена Send ?
    Нет, нам не нужно)
  • RokWeb (17.01.10 21:39) [15]

    > Сергей М.

    Уважаемый Сергей М., лично Вас в эту тему никто не просил заглядывать. Гонора у меня нет, просто попросил помочь. Судя по Вашим постам, Вы слишком агрессивный человек и впредь, прошу Вас не заглядывать в данную тему(заранее спасибо).

    Ах да, к слову - Winsock2 - это 2 версия библиотеки Winsock в Windows.
    Всего Вам доброго :).


    > Anatoly Podgoretsky

    Можно поподробнее по поводу указателей и типизированности?
    Вот полный код, не знаю поможет он решению или нет:

    unit USend;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, ExtCtrls,WinSock2;

    const
     MAX_PACKET_SIZE = $10000; // 2^16

    type
     TByteArray=array of Byte;
     TSendForm = class(TForm)
       Panel3: TPanel;
       Label4: TLabel;
       Label5: TLabel;
       Button2: TButton;
       MessageIP: TEdit;
       MessagePort: TEdit;
       GroupBox1: TGroupBox;
       MessageText: TMemo;
       procedure Button2Click(Sender: TObject);
       procedure MessageTextKeyPress(Sender: TObject; var Key: Char);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     SendForm: TSendForm;

    implementation

    {$R *.dfm}

    function HexToDec(Str: string): Integer;
    var
     i, M: Integer;
    begin
     Result:=0;
     M:=1;
     Str:=AnsiUpperCase(Str);
     for i:=Length(Str) downto 1 do
     begin
       case Str[i] of
         '1'..'9': Result:=Result+(Ord(Str[i])-Ord('0'))*M;
         'A'..'F': Result:=Result+(Ord(Str[i])-Ord('A')+10)*M;
       end;
       M:=M shl 4;
     end;
    end;

    function PushByteMessage(MsgTxt:TStrings):TByteArray;
    var i,j:integer;
    s,buf1:string;
    Massiv:TByteArray;
    k:integer;
    b:Integer;
    Begin
     k:=0;
     for i:=0 to MsgTxt.Count-1 do begin
       s:=MsgTxt.Strings[i];
       While s<>'' do begin
         if pos(' ',s)=0 then begin
           buf1:=s;
           SetLength(Massiv,k+1);
           Massiv[k]:=HexToDec(buf1);
           inc(k);
           s:='';
           break;
         end;
         buf1:=Copy(s,1,pos(' ',s)-1);

         SetLength(Massiv,k+1);
         Massiv[k]:=HexToDec(buf1);
         inc(k);
         s:=Copy(s,pos(' ',s)+1,length(s));
       end;
     end;
     result:=Massiv;

    End;

    //Отправка
    function SendPacket(IP_Addr:string;Port:Word;SendBuff:string):boolean;
    var
     WDat: TWSAData;
     ConnectSock: TSocket;
     Addr: TSockAddr;
     MessageTxt:TByteArray;
    begin
     MessageTxt:=PushByteMessage(SendForm.MessageText.Lines);
     result:=false;
     WSAStartup(MAKEWORD(2,0), WDat);
     ConnectSock:= Socket(AF_Inet, Sock_RAW, ipproto_ip);
     if ConnectSock = invalid_socket then  begin
     ShowMessage('ConnectSock = invalid_socket');
     exit;
     end;
     fillchar(Addr,sizeof(tsockaddr),0);
     Addr.sin_family:= AF_INET;
     Addr.sin_port:=  htons(Port);
     Addr.sin_addr.S_addr := inet_addr(PChar(IP_Addr));
     if Connect(ConnectSock, @Addr,  sizeof(tsockaddr))= socket_error then begin
     ShowMessage('ConnectError');
     exit;
     end;
     if Send(ConnectSock, MessageTxt, Length(MessageTxt), 0)= socket_error then begin
     ShowMessage('Send Error');
     exit;
     end;
     closesocket(ConnectSock);
     wsacleanup;
     result:=true;
    end;

    procedure TSendForm.Button2Click(Sender: TObject);
    begin

    if MessagePort.Text='' then exit;
    if MessageText.Lines.Text='' then exit;
    if MessageIP.Text='' then exit;
    if not SendPacket(MessageIP.Text, StrToInt(MessagePort.text),PChar(MessageText.Lines.Text)) then Showmessage('Сообщение не было отправленно');

    end;

    procedure TSendForm.MessageTextKeyPress(Sender: TObject; var Key: Char);
    begin
     case key of
       '0'..'9':;
       'A'..'F':;
       'a'..'f':;
       #8,#9,#13:;
       ' ':;
     else key:=#0;
     end;
    end;

    end.



    И еще вопрос: решил попробовать подключиться к серверу - подключение проходит и приходит от сервера сообщение(вывожу в Memo1) - M. Тем не менее, пробую оригинальной программой(сетевая игра) подключиться к серверу и "проснифить" клиент игры - вижу, что клиент получает от сервера совсем другой пакет(никак не M), код выглядит так:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    If ClientSocket1.Active then
    Begin
    Button1.Caption := 'Подключиться';
    ClientSocket1.Active := False;
    End
    else begin
    Button1.Caption := 'Отключиться';
    ClientSocket1.Active := True;
    End;
    end;

    procedure TForm1.ClientSocket1Connect(Sender: TObject;
     Socket: TCustomWinSocket);
    begin
    Memo1.Lines.Add('Подключено!');
    end;

    procedure TForm1.ClientSocket1Read(Sender: TObject;
     Socket: TCustomWinSocket);
    begin
    Memo1.Lines.Add('Получено: '+Socket.ReceiveText);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    If ClientSocket1.Active then
    ClientSocket1.Active := False;
    end;

    procedure TForm1.ClientSocket1Error(Sender: TObject;
     Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
     var ErrorCode: Integer);
    begin
    Memo1.Lines.Add('Ошибка: '+IntToStr(ErrorCode));
    end;

    procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
     Socket: TCustomWinSocket);
    begin
    Memo1.Lines.Add('Отключено');
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    If ClientSocket1.Active then
    ClientSocket1.Socket.SendText(HexToStr(Memo2.Text));
    end;

    procedure TForm1.ClientSocket1Connecting(Sender: TObject;
     Socket: TCustomWinSocket);
    begin
    Memo1.Lines.Add('Подключение...');
    end;



    Заранее огромное спасибо!
  • Сергей М. © (17.01.10 21:48) [16]

    > RokWeb   (17.01.10 21:39) [15]


    > Вас в эту тему никто не просил заглядывать


    А я тебе не "дедушка Мороз",  которого "просят")


    > Winsock2 - это 2 версия библиотеки Winsock в Windows


    Да ты что !?
    Да неужели ?!
    А мужики-то и не знают)

    Может тогда ты и на Библии присягнешь, что в штатной поставке D7 есть юнит Winsock2.pas ?
 
Конференция "Сети" » Отправка пакета по сети(Winsock2). [D7, WinXP]
Есть новые Нет новых   [134438   +31][b:0][p:0.007]