Форум: "Сети";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизОтправка пакета по сети(Winsock2). Найти похожие ветки
← →
RokWeb (2010-01-16 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 и по нему отправить нужный мне пакет).
Заранее благодарю!
С Уважением, Алексей!
← →
Сергей М. © (2010-01-16 22:34) [1]
> там показано совсем другое - не то, что я отправлял
И что же он показывает ?
← →
RokWeb (2010-01-17 00:34) [2]Уже исправил SizeOf на Length.
Вот в самой программе на отправку вставил:
12 3A BC D1
Через дебагер увидел следующее значение переменной:
Messagetxt = (18, 58, 188, 209)
В снифере WPE Pro увидел этот же пакет вот так:
44 58 98 00
Совсем запутался... как же все таки надо правильно отправлять пакет так - чтобы сервер его получал в исходном виде(чтобы он получал реально, что Я отправил, а не видоизмененный пакет)
← →
Anatoly Podgoretsky © (2010-01-17 02:18) [3]Не надо ли @MessageTxt[0]
← →
BarakudaX777 (2010-01-17 11:17) [4]MessageTxt:TByteArray;
Это динамичееский Массив чисел.
ЧТо даст @MessageTxt[0]?
Может сама идея отправки не такая. Процедура отправки Send не привязанна к определенному типу. Вот и не знаю в каком виде отправлять данные.
Просто видел снифер там прием от сервера сообщений приходит в массив чисел. Вот и отправку реализовал в таком же виде. Как приходит сообщение, в таком же виде отправляешь а до сервера доходет в другом виде.
Может это быть связанно с кодировкой? Кажется там сервер в кодировке UTF8 работает. Представляет информацию. Вот чтот совсем запутался!
← →
RokWeb (2010-01-17 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
Почему же отправляет не то, что нужно?
← →
Сергей М. © (2010-01-17 17:43) [6]
> ЧТо даст @MessageTxt[0]?
Даст требуемый результат.
← →
RokWeb (2010-01-17 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
← →
Сергей М. © (2010-01-17 18:44) [8]И чего ?
Ты не в состоянии понять то что говорит тебе компилятор ?
← →
RokWeb (2010-01-17 19:44) [9]Уважаемый, зачем так агрессивно? Дело в том, что данной функции я не передаю констант :).
← →
Сергей М. © (2010-01-17 20:09) [10]И чего, "неагрессивный" ты наш ?
Ты уже в теме облажался с передачей указателя.
Гонор свой при этом не желаешь умерить ?
← →
Anatoly Podgoretsky © (2010-01-17 20:26) [11]Видимо надо использовать указатель, типизированый или нет.
Вообще это твоя задача посмотреть объявление функции, никто другой делать это особо не будет.
← →
Сергей М. © (2010-01-17 20:31) [12]
> Anatoly Podgoretsky © (17.01.10 20:26) [11]
А ему по барабану.
Ему здесь обязаны.
← →
Anatoly Podgoretsky © (2010-01-17 21:11) [13]> Сергей М. (17.01.2010 20:31:12) [12]
А нам не хочется. Оно нам нужно?
← →
Сергей М. © (2010-01-17 21:31) [14]
> Оно нам нужно?
Разбираться откуда взялся Winsock2 и как там объявлена Send ?
Нет, нам не нужно)
← →
RokWeb (2010-01-17 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;
Заранее огромное спасибо!
← →
Сергей М. © (2010-01-17 21:48) [16]
> RokWeb (17.01.10 21:39) [15]
> Вас в эту тему никто не просил заглядывать
А я тебе не "дедушка Мороз", которого "просят")
> Winsock2 - это 2 версия библиотеки Winsock в Windows
Да ты что !?
Да неужели ?!
А мужики-то и не знают)
Может тогда ты и на Библии присягнешь, что в штатной поставке D7 есть юнит Winsock2.pas ?
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.076 c