Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.04.13;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.006 c
15-1204204156
dr_creigan
2008-02-28 16:09
2008.04.13
DDK XP


2-1205424109
HelloEverybody
2008-03-13 19:01
2008.04.13
Компилятор пропускает команду...


2-1205763221
Berkoot
2008-03-17 17:13
2008.04.13
Надстрочный индекс в Delphi


15-1204081129
Slider007
2008-02-27 05:58
2008.04.13
С днем рождения ! 27 февраля 2008 среда


2-1205594808
DJ_UZer
2008-03-15 18:26
2008.04.13
Цвета в combobox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский