Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.04.13;
Скачать: CL | DM;

Вниз

ClientSocket и ServerSocket   Найти похожие ветки 

 
Aleksandr   (2008-03-20 17:48) [0]

у меня два вопроса по сокетам )

1. отправляю сообщение
TMess = packed record

procedure TForm1.Button1Click(Sender: TObject);
var  Mess: TMess;
begin
 Mess.ID_DB:="3243643214364654645";
 Mess.ID_CLIENT:=strComp.Text;
 Mess.command:="send_mess";
 Mess.Txt:=strMess.Text;

 ClientSocket.Host:=strComp.Text;
 ClientSocket.Active:=true;
 ClientSocket.Socket.SendBuf(Mess,SizeOf(TMess));
 ClientSocket.Active:=false;
end;

почему сообщение отправляется только после того как я второй раз нажму на кнопку ?

2. принимаем сообщение
procedure TForm1.ServerSocketClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 buf: array[1..MaxSize] of byte;
 Size: Word;
 Mess: ^TMess;
begin
 memo1.Lines.Add("читаем");
 Size:=Socket.ReceiveLength; {Принимаемое кол-во байт}
 Socket.ReceiveBuf(buf,Size);
 New(Mess);
 BufToPct(Mess^,buf,Size);
 memo1.Lines.Add(Mess^.ID_DB);
 memo1.Lines.Add(Mess^.ID_CLIENT);
 memo1.Lines.Add(Mess^.command);
 memo1.Lines.Add(Mess^.Txt);
 memo1.Lines.Add("конец");
 Dispose(Mess);
end;

все нормально принимается, только после того как сообщение принялось у меня само приложение закрывается (. из чего это может быть ?


 
Palladin ©   (2008-03-20 17:59) [1]


> почему сообщение отправляется только после того как я второй
> раз нажму на кнопку ?

уверен? а по каким признакам ты определяешь что оно не отправилось на первый раз, но отправилось на второй?


> ClientSocket.Socket.SendBuf(Mess,SizeOf(TMess));

почему не анализируется результат?


>  Size:=Socket.ReceiveLength; {Принимаемое кол-во байт}
>  Socket.ReceiveBuf(buf,Size);

почему не анализируется результат?


> BufToPct(Mess^,buf,Size);

это что за такое?


> все нормально принимается, только после того как сообщение
> принялось у меня само приложение закрывается (. из чего
> это может быть ?

космические лучи


 
Aleksandr   (2008-03-20 18:02) [2]

procedure BufToPct(var Packet; var buf; Size: Word);
{Конвертация из буфера в пакет}
var
 arPacket: array[1..MaxSize] of byte absolute Packet;
 arBuf: array[1..MaxSize] of byte absolute buf;
 i: Word;
begin
 for i:=1 to Size do
   arPacket[i]:=arBuf[i];
end;


 
Aleksandr   (2008-03-20 18:03) [3]

"почему сообщение отправляется только после того как я второй раз нажму на кнопку ?"

решил так, потому что пробовал передовать обычные тесктовые сообщения и сервер принимал их только после того как я нажимал второй раз на кнопку )


 
Palladin ©   (2008-03-20 18:09) [4]

так проверяй, проверяй результат приема/отправки данных, это раз.

два: ты чего творишь в приеме?

procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: array[1..MaxSize] of byte;
Size: Word;
Mess: ^TMess;
begin
memo1.Lines.Add("читаем");
Size:=Socket.ReceiveLength; {Принимаемое кол-во байт}
Socket.ReceiveBuf(buf,Size);
New(Mess); // память выделена только под одну запись
BufToPct(Mess^,buf,Size); // читаем все что только можно, а глядя на исходник этой функции я вижу, что в случае приема данных больше размером чем запись ты полезешь туда куда не надо
memo1.Lines.Add(Mess^.ID_DB);
memo1.Lines.Add(Mess^.ID_CLIENT);
memo1.Lines.Add(Mess^.command);
memo1.Lines.Add(Mess^.Txt);
memo1.Lines.Add("конец");
Dispose(Mess);
end;


что за безолаберность вообще?


 
Palladin ©   (2008-03-20 18:09) [5]

да и кстати какого типа поле TMess.Txt и TMess.command ?


 
Slym ©   (2008-03-21 05:10) [6]

режим работы ClientSocket не озвучен, но судя по ServerSocketClientRead - всетаки неблокирующий режим, а в неблокирующем режиме так делать нельзя:
ClientSocket.Active:=true;
ClientSocket.Socket.SendBuf(Mess,SizeOf(TMess));//<<нет гарантии что Active=true
ClientSocket.Active:=false;


 
Slym ©   (2008-03-21 05:37) [7]

Palladin ©   (20.03.08 18:09) [5]
+1...
если string то, передается не строка, а указатель на нее :) всеравно что копировать файлы на др комп "ярлычком" на него :)


 
Aleksandr   (2008-03-21 09:45) [8]

все выслушал, спасибо за критику )

я новичек, а с сокетами вообще работаю раз второй ))
так прошу помочь и подсказать что где надо сделать

TMess = packed record
 ID_DB: string[32];
 ID_CLIENT: String[50];
 command: String[50];
 Txt: String[200];
 end;

спасибо за помощь )


 
Aleksandr   (2008-03-21 09:47) [9]

сообщение принимается, этот код отрабатывается
memo1.Lines.Add(Mess^.ID_DB);
memo1.Lines.Add(Mess^.ID_CLIENT);
memo1.Lines.Add(Mess^.command);
memo1.Lines.Add(Mess^.Txt);
memo1.Lines.Add("конец");

но после программа сама закрывается (


 
Сергей М. ©   (2008-03-21 09:53) [10]


> с сокетами вообще работаю раз второй


А с отладчиком какой ?


 
Aleksandr   (2008-03-21 10:24) [11]

может хватит глумится, подскажите что надо делать, где искать )

желательно с примерами, если не затруднит )


 
Сергей М. ©   (2008-03-21 10:29) [12]


> может хватит глумится


А сам-то не глумишься ?

У тебя под рукой есть отладчик, вот и воспользуйся им для поиска ошибки.

И компоненты эти вовсе ни причем - с тем же "успехом" можно долго и нудно канючить помощь в поиске ошибки в программе, использующей любой иной компонент.


 
Aleksandr   (2008-03-21 10:35) [13]

да дело в том что я отладчиком прошелся по коду приемы сообщения
и не чего там не увидел, отрабатывается последняя строчка и программа сама закрывается (


 
Сергей М. ©   (2008-03-21 10:39) [14]


> я отладчиком прошелся по коду приемы сообщения
> и не чего там не увидел


Значит не туда смотрел, раз не увидел.

А чтобы увидеть, следует сначала выполнить все рекомендации, данные тебе выше в отношении твоего безалаберного кода.


 
Slym ©   (2008-03-21 10:44) [15]

var InBuffer:string;
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
 s:string;
 Mess:TMess;
begin
memo1.Lines.Add("читаем");
InBuffer:=InBuffer+Socket.ReceiveText;
while length(InBuffer)>SizeOf(Mess) do
begin
 s:=copy(InBuffer,1,SizeOf(Mess));
 delete(InBuffer,1,SizeOf(Mess));
 move(PChar(s)^,Mess,SizeOf(Mess);
 memo1.Lines.Add(Mess.ID_DB);
 memo1.Lines.Add(Mess.ID_CLIENT);
 memo1.Lines.Add(Mess.command);
 memo1.Lines.Add(Mess.Txt);
 memo1.Lines.Add("конец");
end;
end;


 
Slym ©   (2008-03-21 10:45) [16]

while length(InBuffer)>=SizeOf(Mess) do


 
Aleksandr   (2008-03-21 11:25) [17]

в Mess пусто и при попытке прочитать от туда
memo1.Lines.Add(Mess.ID_DB); вылетает ошибка


 
han_malign ©   (2008-03-21 11:48) [18]


> но после программа сама закрывается (
>



> > BufToPct(Mess^,buf,Size); // читаем все что только можно,
> >  а глядя на исходник этой функции я вижу, что в случае приема данных больше размером чем запись ты полезешь туда куда не надо

- после того как ты затер служебную информацию менеджера памяти для выделенного блока(конкретней - раньше там был повторный размер-флаг для валидации(сечас там кажется прямые ссылки для двусвязного списка - глубоко не копался еще) ) данными превышающими размер буфера, на Dispose(Mess) - возникает Invalid pointer operation(EInvalidPointer).
На нем все и вылетает, а вот хлопнет ли при этом дверью - зависит от того насколько целостность кучи повреждена - на экземпляр класса EInvalidPointer тоже память выделять надо...

З.Ы. Ситуатции с "теряющимися исключениями" плотно не отлаживал - поэтому насчет памяти под экземпляр исключения - чисто предположение...

З.З.Ы. На  memo1.Lines.Add - алокируются временные строки, но видимо менеджер памяти находит место не доходя до разрушенной цепочки(пока везет)... Так что - могло вылетать и до последней строки.


 
Сергей М. ©   (2008-03-21 12:00) [19]


> han_malign ©   (21.03.08 11:48) [18]


Да просто стек засран)

Ты давай не глумись уже, автору не умные слова нужны про менеджеры памяти и прочую шнягу, а сделать так чтобы ошибка не "вылетала").. А отладчик ему что корове седло)


 
han_malign ©   (2008-03-21 12:33) [20]

о - там еще и стек убивается на

buf: array[1..MaxSize] of byte;
...
Size:=Socket.ReceiveLength; {Принимаемое кол-во байт}
Socket.ReceiveBuf(buf,Size);

поэтому EInvalidPointer может и не быть


> в Mess пусто и при попытке прочитать от туда
> memo1.Lines.Add(Mess.ID_DB); вылетает ошибка

- не нравится мне как ReceiveText реализован, на многоядерном можно грабли огрести

попробуй так
TForm1 = class(TForm)
...
private
   FDepth: integer;
   FBuf: array[word]of byte;
end;
...
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var offs: integer;
begin
  memo1.Lines.Add("читаем");
  inc(FDepth, Socket.ReceiveBuf(FBuf[FDepth], sizeof(FDepth) - FDepth));
  offs:= 0;
  while(FDepth - offs >= sizeof(TMess))do
  with( PMess(@FBuf[offs])^ )do begin
     memo1.Lines.Add(ID_DB);
     memo1.Lines.Add(ID_CLIENT);
     memo1.Lines.Add(command);
     memo1.Lines.Add(Txt);
     memo1.Lines.Add("конец");
     inc(offs, sizeof(TMess));
  end;
  dec(FDepth, offs);
  if( FDepth > 0 )then move(FBuf[offs], FBuf[0], FDepth);
end;

ну и неплохо бы иметь в пакете тэг(магическое слово) по которому можно начала пакета найти


 
han_malign ©   (2008-03-21 12:35) [21]

Socket.ReceiveBuf(FBuf[FDepth], sizeof(FBuf) - FDepth)



Страницы: 1 вся ветка

Текущий архив: 2008.04.13;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.024 c
6-1184599713
yaJohn
2007-07-16 19:28
2008.04.13
ISAPI DLL, файл больше 2 Гб


15-1204204894
Виталий Панасенко(дом)
2008-02-28 16:21
2008.04.13
Механизм переоценки мат.ценностей(товара)


15-1204398665
TIF
2008-03-01 22:11
2008.04.13
Canvas у... TWebBrowser


11-1180814127
Rusya
2007-06-02 23:55
2008.04.13
А теперь ecmListEdit


15-1204535379
Vemer
2008-03-03 12:09
2008.04.13
Ошибка с rtl60.bpl на новойм компьютере.