-
Здравствуйте. Есть следующая задача - необходимо отправить пакет по сети без каких либо его видоизменений(чтобы он точно соответствовал тому, что я введу например). Есть следующий код:
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 и по нему отправить нужный мне пакет).
Заранее благодарю!
С Уважением, Алексей!
-
> там показано совсем другое - не то, что я отправлял
И что же он показывает ?
-
Уже исправил SizeOf на Length.
Вот в самой программе на отправку вставил: 12 3A BC D1
Через дебагер увидел следующее значение переменной: Messagetxt = (18, 58, 188, 209)
В снифере WPE Pro увидел этот же пакет вот так: 44 58 98 00
Совсем запутался... как же все таки надо правильно отправлять пакет так - чтобы сервер его получал в исходном виде(чтобы он получал реально, что Я отправил, а не видоизмененный пакет)
-
Не надо ли @MessageTxt[0]
-
MessageTxt:TByteArray; Это динамичееский Массив чисел.
ЧТо даст @MessageTxt[0]?
Может сама идея отправки не такая. Процедура отправки Send не привязанна к определенному типу. Вот и не знаю в каком виде отправлять данные. Просто видел снифер там прием от сервера сообщений приходит в массив чисел. Вот и отправку реализовал в таком же виде. Как приходит сообщение, в таком же виде отправляешь а до сервера доходет в другом виде.
Может это быть связанно с кодировкой? Кажется там сервер в кодировке UTF8 работает. Представляет информацию. Вот чтот совсем запутался!
-
Дело не в сервере... Опишу поподробнее ситуацию: Пишется некая программа для игры, её суть - перехватить входящий пакет, проанализировать и отправить исходящий пакет на сервер. Для "теста" отправки пакета - я перехватываю НОРМАЛЬНЫЙ пакет игры: 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 Почему же отправляет не то, что нужно?
-
> ЧТо даст @MessageTxt[0]?
Даст требуемый результат.
-
Сделал так: if Send(ConnectSock, @MessageTxt[0], Length(MessageTxt), 0)= socket_error then begin Ошибка при компиляции: [Error] USend.pas(111): Constant object cannot be passed as var parameter
-
И чего ? Ты не в состоянии понять то что говорит тебе компилятор ?
-
Уважаемый, зачем так агрессивно? Дело в том, что данной функции я не передаю констант :).
-
И чего, "неагрессивный" ты наш ?
Ты уже в теме облажался с передачей указателя.
Гонор свой при этом не желаешь умерить ?
-
Видимо надо использовать указатель, типизированый или нет. Вообще это твоя задача посмотреть объявление функции, никто другой делать это особо не будет.
-
> Anatoly Podgoretsky © (17.01.10 20:26) [11]
А ему по барабану. Ему здесь обязаны.
-
> Сергей М. (17.01.2010 20:31:12) [12]
А нам не хочется. Оно нам нужно?
-
> Оно нам нужно?
Разбираться откуда взялся Winsock2 и как там объявлена Send ? Нет, нам не нужно)
-
> Сергей М.
Уважаемый Сергей М., лично Вас в эту тему никто не просил заглядывать. Гонора у меня нет, просто попросил помочь. Судя по Вашим постам, Вы слишком агрессивный человек и впредь, прошу Вас не заглядывать в данную тему(заранее спасибо). Ах да, к слову - 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;
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
public
end;
var
SendForm: TSendForm;
implementation
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; Заранее огромное спасибо!
-
> RokWeb (17.01.10 21:39) [15]
> Вас в эту тему никто не просил заглядывать
А я тебе не "дедушка Мороз", которого "просят")
> Winsock2 - это 2 версия библиотеки Winsock в Windows
Да ты что !? Да неужели ?! А мужики-то и не знают)
Может тогда ты и на Библии присягнешь, что в штатной поставке D7 есть юнит Winsock2.pas ?
|