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

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

Проблема с передачей файла через Сокеты.... [D6, WinXP]


SeNtiMeL ©   (2003-02-19 03:26:00) 

В общем проблема передачи файла через TServerSocket клиенту TClient Socket...
ServerSocket отправляет данные полностью (по крайней мере программа выводит полную отправку). Но клиент не может нормально принять эти данные, он не дополучает некоторые пакеты.
Тестирую программу на одном компьютере с IP LocalHost....
Можно отправлять файл через SendStream, но тогда не могу подсчитать кол-во отправленных данных....
Ниже привожу код программы, может есть ошибка.

Отправка сервером:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ms : TMemoryStream;
Buf : Pchar;
copy : Boolean;
lsize : integer;
begin
// Получено подверждение пересылки
if Socket.ReceiveText = "OK" then
begin
ms:= TMemoryStream.Create;
ms.LoadFromFile("f:\test.mp3");
ms.Position:= 0;
Socket.SendText(IntToStr(ms.Size)); // Отправляем размер файла.
copy:=True;


While Copy = true do
begin
Application.ProcessMessages;

lsize:=Min(ms.Size-ms.Position,1024);
GetMem(Buf,Lsize);
if lsize <> 0 then
begin
ms.Read(Buf^,lsize);
Application.ProcessMessages;
ServerSocket1.Socket.Connections[0].SendBuf(buf^,lsize);

Label1.Caption:="Отправлено: "+IntToStr(ms.Position)+" из " + IntToStr(ms.Size);
end
else Copy := False;
FreeMem(Buf);
end;
ms.Free;
end;
end;

Получение клиентом:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var s, sl, tmp: string;
s2 : Pchar;
x,x1 : Real;
y,lsize : Integer;

begin
s:=Socket.ReceiveText;

if fl = 1 then
begin
if not Reciving then
begin
sl:=Copy(s,1,Length(s));
DataSize:= StrToInt(sl);
Data:= TMemoryStream.Create;
Delete(s, 1, Length(sl));
Reciving:= true;
end;
try
Data.Write(s[1], length(s));
x:=Data.Size * 100 div DataSize;
x1:=Int(x);
tmp:=FloatToStr(x1);
Form2.ProgressBar1.Position:=StrToInt(tmp);
Form2.Label3.Caption:="Получено "+ IntToStr(Data.Size)+ " из " + IntToStr(DataSize);

if Data.Size = DataSize then
begin
Data.Position:= 0;
Data.SaveToFile("c:\test.mp3");
Data.Free;
Reciving:= false;
Socket.Close;
Form2.Button1.Enabled:=True;
Form2.Label3.Caption:="Файл получен ";
end;
except
Data.Free;
end;

end;


mrcat   (2003-02-23 00:39:00) [1]

>>хм.... 8К буфер наполняется мнгновенно...

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

Читай: Note that this may be less than the length of the string S if the socket is nonblocking.


>>И я использую не SENDTEXT а SENDBUF это разные вещи.... function TCustomWinSocket.SendText(const s: string): Integer;
begin
Result := SendBuf(Pointer(S)^, Length(S));
end;


SeNtiMeL   (2003-02-23 00:15:00) [2]

А гдеж взять исходники то.... Их не наблюдается в поставки дельфи...


Digitman   (2003-02-22 13:30:00) [3]


> SeNtiMeL


Чем же они "разные" ? ты хоть в исходники заглядывал ? Все, что делает SendText - прямой вызов SendBuf


SeNtiMeL   (2003-02-22 00:28:00) [4]

хм.... 8К буфер наполняется мнгновенно...
И я использую не SENDTEXT а SENDBUF это разные вещи....


mrcat   (2003-02-20 00:25:00) [5]

SendText returns the number of bytes sent. Note that this may be less than the length of the string S if the socket is nonblocking.

что делать будете, в случае, если буфер "частично" полон?
Ваше условие не выполнится:
if ServerSocket1.Socket.Connections[0].SendBuf(buf^,lsize) = -1 then goto point1;


SeNtiMeL   (2003-02-19 22:08:00) [6]

Спасибо, но я уже сам разобрался :)

В посылке данных нужно было добавить проверку на очередь отправки, если она полная то попробовать еще раз....
Вот часть кода

ms.Read(Buf^,lsize);
point1: // метка для новой попытки
Application.ProcessMessages;
if ServerSocket1.Socket.Connections[0].SendBuf(buf^,lsize) = -1 then goto point1; // если очередь полная, то идем к метке и пробуем еще раз...


Fredericco   (2003-02-19 21:45:00) [7]

Наша бесседа с Digitman"ом, в завершении которой все подробно описано.
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1042188128&n=4


SeNtiMeL   (2003-02-19 21:12:00) [8]

Если не сложно, то опиши поподробней об этом...


Digitman   (2003-02-19 09:42:00) [9]

1. нет анализа результатов выполнения методов SendText, SendBuf
2. нет обработки события OnClientWrite


Наверх

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