Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как послать файл с ServerSocket и принять его на ClientSocket?


Страницы:   1 2

kosmach ©   (2002-08-05 10:17:00) 

У ServerSocket есть три до боли простых по своей логике метода:
SendText, SendBuffer и SendStream. Первые два прекрасно работают, впрочем последний тоже работает, данные то клиенту приходят и правильно приходят, но сам он выдает ошибку: "Access violation at adress 00000000",;
Вот код сервера:

procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
FS: TFileStream;
St: String;
begin
St:=Socket.ReceiveText;
if St="Send" then begin
try
FS:=TFileStream.Create("file.txt", fmOpenRead);
Socket.SendStream(FS);
finally
FS.Free;
end;
end;
end;


А вот клиента:


procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
FS: TFileStream;
buf: PChar;
size: longint;
begin
Size:=Socket.ReceiveLength;
GetMem(Buf, Size);
Socket.ReceiveBuf(buf^,size);
FreeMem(buf);
end;


Вроде бы все просто, а не работает, даже предположить не могу, что не так, может кто-нибудь, что-нибудь заметит.


ACR   (2002-08-06 08:46:00) [1]

>kosmach ©
вот тебе поле для иследований


глобальная переменная
ReadyToTransmit : boolean;


OnFormCreate
{
ReadyToTransmit := false;


}

OnClientDisconnect
{
ReadyToTransmit := false;

}


OnServerSockeClientWrite !
{
ReadyToTransmit := trueж < Здесь передачик либо только что инициализировлся и готов передовать либо только что передал последний байт из буфера и сново готов передавать

}

OnServerSocketClientRead
{

S := CreateStream;

Socket.SendStream(S);

while (not ReadyToTransmit) do Application.ProcessMessage;

S.Free;

try...finally ваще убери они не для этого предназначены
}


думаю разберешся с моим псевдо кодом
от AV ты избавишся... даже возможно все будет работать
но всеравно у тя получится полная лажа...


St:=Socket.ReceiveText;
if St="Send" then // ты уверен что тут получишь иммено Send?
можешь сначало получить "S" патом "е" и т.д. а можешь "Se" а патом "end" а St никогда небудет равна "Send" хотя если сеть быстрая то все будет тип топ


kosmach   (2002-08-06 08:16:00) [2]


> ACR ©

Насчет
> не 1 а (-1) чуешь разницу?
> а еще ReceiveLength может вернуть 0

все ясно, разберусь. А вот как быть с
> try
> FS:=TFileStream.Create("file.txt", fmOpenRead);
> Socket.SendStream(FS); < Вот эта строчка никуда ничего
> неотправляет! ана всеголишь долбится в сокет на предмет
> готовности передачика и ставит байтики в очередь на отпраку
>
> finally
> FS.Free; // здесь сокет вожможно еще передает твой паток
> по сети а ты этот паток беспащадно убиваешь... кто ты после
> этого?
> Granted AV Coder!
> end;

Подскажи, пожалуйста


ACR   (2002-08-06 08:04:00) [3]

>karbo ©
Сматрите внимательно:

try
FS:=TFileStream.Create("file.txt", fmOpenRead);
Socket.SendStream(FS); < Вот эта строчка никуда ничего неотправляет! ана всеголишь долбится в сокет на предмет готовности передачика и ставит байтики в очередь на отпраку

finally
FS.Free; // здесь сокет вожможно еще передает твой паток по сети а ты этот паток беспащадно убиваешь... кто ты после этого?
Granted AV Coder!
end;

>kosmach ©
не 1 а (-1) чуешь разницу?
а еще ReceiveLength может вернуть 0 представляешь какая анархия в твоем коде будет?


kosmach   (2002-08-06 07:16:00) [4]


> ACR ©

Ну и черт с ним, пускай возвращает 1, это значит, что реально я принял 1 байтик, ну и не хай, остальные в следующий раз приму и запишу куда надо.


kosmach   (2002-08-06 07:11:00) [5]


> karbo ©

Я это с самого начала говорил, только создовать поток в FormCreate я не могу, так как надо будет слать несколько файлов и влюбом случае, придется убивать поток, а потом создовать его, с новым именем файла.
А Вообщето, я считал, что можно ограничиться try ... finally...end; и никаких ошибок быть не должно.


> cyborg ©

Согласен, вчера я все время чего-то переделывал, по советам некоторых, вот полный код:

var
Form1: TForm1;
FS: TFileStream;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket.Open;
end;

procedure TForm1.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
if FileExists("DL\file.txt") then DeleteFile("DL\file.txt");
FS:=TFileStream.Create("DL\file.txt", fmCreate);
end;

procedure TForm1.ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
FS.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ClientSocket.Socket.SendText("Send");
end;

procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
FS: TFileStream;
St: String;
buf: PChar;
size: longint;
begin
St:=Socket.ReceiveText;
if St="Send" then begin
try
FS:=TFileStream.Create("file.txt", fmOpenRead);
Socket.SendStream(FS);
finally
FS.Free;
end;
end;
end;

procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: PChar;
size, s: longint;
begin
Size:=Socket.ReceiveLength;
GetMem(Buf, Size);
try
S:=Socket.ReceiveBuf(Buf^, Size);
FS.WriteBuffer(buf^, S);
finally
FreeMem(buf);
end;
end;

end.


karbo   (2002-08-06 03:50:00) [6]

В коде сервера в самом деле зарыта AV:

procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
FS: TFileStream;
St: String;
begin
St:=Socket.ReceiveText;
if St="Send" then begin
try
FS:=TFileStream.Create("file.txt", fmOpenRead);
Socket.SendStream(FS);
finally
FS.Free;//
<----- Вот здесь AV и всплывает !
end;
end;
end;

Почему так происходит, объяснить не берусь, но совет дам : не надо так быстро убивать FS после Socket.SendStream.

Лучше объявить FS как глобальную переменную и вызывать ее Create и Free только один раз - где нибудь в FormCreate и FormClose.


cyborg   (2002-08-05 21:39:00) [7]

kosmach © напиши полный код твоих сокетов, тут нихрена не понятно, в одном отрывке у тебя одно, в другом другое, где-то кастрировано и хочешь что бы тебе дали ответ на то, что ты сам не можешь сказать что.
И буфер нужно делать на Pointer-е, а не на PChar-е.


ACR   (2002-08-05 18:25:00) [8]

>Digitman © Снобизм тежолая болезнь

>kosmach © (05.08.02 14:28)

ReceiveBuf могет -1 вернуть прикинь какая лажа выйдет...


Digitman   (2002-08-05 15:15:00) [9]

Разговор окончен. Ты показал себя.


kosmach   (2002-08-05 15:01:00) [10]

Вот мой код, уже указанный выше:

S:=Socket.ReceiveBuf(Buf^, Size);
FS.WriteBuffer(buf^, S);


Разьве S - это не то, что возвратила функция ReceveBuf?


kosmach   (2002-08-05 14:56:00) [11]

Извени


kosmach   (2002-08-05 14:50:00) [12]

В хэлп я загляну, а вот ты - воспитатель х..в, уже не одному десятку человек сказал вот эту фразу: "размер_реально_прочитанных_данных_возвращенный_ф-цией_ReceiveBuf (!!!!!!!!!!!!!!!!!!)", и хоть бы раз забил на свою вонючую принципиальность, и прямо сказал как надо делать.


Digitman   (2002-08-05 14:44:00) [13]

Я тебе еще раз повторяю :

FS.WriteBuffer(buf^, размер_реально_прочитанных_данных_возвращенный_ф-цией_ReceiveBuf(!!!!!!!!!!!!!!!!!!));


Что у тебя содержит переменная Size на момент вызова WriteBuffer() ? Если ты считаешь, что Size - это размер реально прочитанных данных, то - вперед, в хэлп по методам ReceiveLenght() и ReceiveBuf(). С ЭТОГО надо начинать - с внимательнейшего чтения хэлпа ! А не со слепого передирания неизвестно где взятых "корявых" примеров.


kosmach   (2002-08-05 14:28:00) [14]

Во-первых, Пушкин здесь не причем, все что ты мне написал, я достаточно внимательно прочитал, во-вторых, я зделал все как ты мне "велел". Поток для записи я открыл еще в ClientSocket.onConnect, а в ClientSocket.onRead сделал следующее

procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: PChar;
size, s: longint;
begin
Size:=Socket.ReceiveLength;
GetMem(Buf, Size);
try
S:=Socket.ReceiveBuf(Buf^, Size);
FS.WriteBuffer(buf^, S);
finally
FreeMem(buf);
end;
end;


И поверь мне, ничего не изменилось.


Digitman   (2002-08-05 14:12:00) [15]

Эту ошибку я уже тебе указал в постинге от (05.08.02 11:48)

Конечно, там я обращался не к тебе, а к Пушкину, и написал там полную чушь - чего ее читать-то ?
Поэтому, очевидно, ты его (постинг) проигнорировал, даже не вникнув.

Вот - более-менее корректный код взамен соответствующего:

FS:=TFileStream.Create("DL\file.txt", fmOpenReadWrite);
try
FS.Seek(0, soFromEnd);
FS.WriteBuffer(buf^, размер_реально_прочитанных_данных_возвращенный_ф-цией_ReceiveBuf);
finally
FS.Free;
end;


kosmach   (2002-08-05 13:52:00) [16]

Последняя строчка, на которой я жму F7 это FS.Free в procedure TForm1.ServerSocketClientRead, после чего всякое выделение пропадает, проходит несколько секунд, и вместо того, чтобы перейти к обработчику события ClientSocket onRead, выскакивает ошибка.


Digitman   (2002-08-05 13:47:00) [17]

Ну так на какой строчке-то AV ?? Ты F7 для чего жмешь-то ? Просто так ? Или-таки - для контроля исполнения конкретной строчки ?

Где , в каком месте ты ставишь точку останова ?


kosmach   (2002-08-05 13:23:00) [18]

Что такое внутренний отладчик я знаю, да и пользоваться им мне приходилось. В данном случае, я прохожу полностью процедуру отпрвки потока с сервера, после чего еще пару раз нажав F7 выскакивает сообщение об AV.


Digitman   (2002-08-05 13:14:00) [19]

>kosmach

"что-нибудь дельное" я тебе уже посоветовал : разберись и укажи, на какой строчке ты получаешь AV - после этого я скажу тебе, источник ошибки. Для этого в Делфи есть встроенный интегрированный отладчик, читать лекцию по использованию которого у меня нет ни малейшего желания.


kosmach   (2002-08-05 13:07:00) [20]

Раз уж ты такой "модный", то мог бы не задирать так высоко нос, а посоветовать что-нибудь дельное, если не по Socket"ам, то хоть по тому, что ты мне там наговорил: по поводу отладки и прочего. А что касается Socket"ов то действительно напиши статью, что-бы тот кто дорос до этого, тот бы понял как делать, а кто нет - понял, что нужно еще многому учиться. Вобщем, вместо того, чтоб говорить "...обязан познать...", посоветовал бы как это сделать.
Одно утешает, хоть поорали друг на друга вдоволь, а с отправкой файлов, рано или поздно я все равно разберусь.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо