Форум: "Начинающим";
Текущий архив: 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