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

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

ClientSocket [D6, Win2k]


Страницы:   1 2 3 4

Dmitriy Polskoy ©   (2002-11-13 14:43:00) 

Подскажите, как сделать так, чтобы ClientSocket принимал ровно столько сколько передает ServerSocket. Объясняю - ServerSocket в
OnClientRead получает имя файла и затем передает его клиенту по 500 байт
AssignFile(SrcFile, FileName);
Reset(SrcFile,1);
try
repeat
BlockRead(SrcFile, Buffer, SizeOf(Buffer), BytesRead);
ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
until BytesRead = 0;
finally
CloseFile(SrcFile);
end;

А клиент принимет, но не 500 байт за раз, а другое число байт.
Я знаю, что это нормально, но как сделать, чтобы и принимал 500.
А то файл бьется.


Digitman   (2002-11-14 11:01:00) [41]


> По-моему надо Socket.ReceiveLength


Ну надо так надо. Несущественные ляпы сам исправляй.


> А где же заполняется буфер


А это что - по-твоему ?


ActualBytesRead := Socket.ReceiveBuf(temp_bufptr^, BytesRemainsToRead);



> И что-то вообще не очень понятно


Что непонятно ? Конкретно ?


Dmitriy Polskoy   (2002-11-14 10:58:00) [42]

2 Digitman © (14.11.02 10:50)
Да написал я ему, а он молчит. Ну хоть ты не молчи.


Dmitriy Polskoy   (2002-11-14 10:53:00) [43]

2 Digitman © (14.11.02 10:25)
Не, не работает

> if ReceiveLength = 0 then Exit;

По-моему надо Socket.ReceiveLength


> BlockWrite(DestFile, Buffer, TotalBytesRead,BytesWritten);
>

А где же заполняется буфер
И что-то вообще не очень понятно. Если можешь объясни, а?


Digitman   (2002-11-14 10:50:00) [44]

Обратись к <V_Pavel>

Устал я уже писать одно и тоже.
Не далее как вчера он получил мылом работающий вариант передатчика с использованием SendStream.


Dmitriy Polskoy   (2002-11-14 10:38:00) [45]

А помоги с сервером. Я делаю так, но иногда сервер передает неправильное кол-во байт.


procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Res, LasrPos: Integer;
begin
FileName := Socket.ReceiveText;

AssignFile(SrcFile, FileName);
Reset(SrcFile,1);
try
repeat
BlockRead(SrcFile, Buffer, SizeOf(Buffer), BytesRead);
Res := ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
while (Res = -1) do
begin
Sleep(1);
Res := ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
end;
sum := sum + Res;
label1.Caption := inttostr(sum);
until BytesRead = 0;
finally
CloseFile(SrcFile);
end;
end;


Digitman   (2002-11-14 10:25:00) [46]


var
TotalBytesRead : Integer = 0;
Buffer : Pointer;
...

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
ActualBytesRead: Integer;
BytesRemainsToRead : Integer;
temp_bufptr: PChar;
begin
if ReceiveLength = 0 then Exit;
BytesRemainsToRead := 500 - TotalBytesRead;
temp_bufptr := Buffer;
Inc(temp_bufptr, TotalBytesRead);
ActualBytesRead := Socket.ReceiveBuf(temp_bufptr^, BytesRemainsToRead);
if ActualBytesRead >= 0 then
begin
Inc(TotalBytesRead, ActualBytesRead);
if TotalBytesRead = 500 then
begin
BlockWrite(DestFile, Buffer, TotalBytesRead,BytesWritten);
TotalBytesRead := 0;
end;
end;


Dmitriy Polskoy   (2002-11-14 10:13:00) [47]

Еще пробовал так

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
Res, LastPos, Temp: integer;
begin
BytesRead := Socket.ReceiveLength;
Temp := BytesRead;
Res := Socket.ReceiveBuf(Buffer, BytesRead);
BytesRead := BytesRead - Res;
while (BytesRead > 0) do
begin
LastPos := LastPos + Res;
Res := Socket.ReceiveBuf(Buffer[LastPos+1], BytesRead);
if Res = -1 then Res := 0;
BytesRead := BytesRead - Res;
end;
BlockWrite(DestFile, Buffer, Temp, BytesWritten);
end;


Dmitriy Polskoy   (2002-11-14 09:57:00) [48]

Я делаю так, но что-то не работает

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
Res: integer;
begin
BytesRead := Socket.ReceiveLength;
Res := Socket.ReceiveBuf(Buffer, BytesRead);
BlockWrite(DestFile, Buffer, Res, BytesWritten);
BytesRead := BytesRead - Res;
while (BytesRead > 0) do
begin
FillChar(Buffer, SizeOf(Buffer), 0);
Res := Socket.ReceiveBuf(Buffer, BytesRead);
BlockWrite(DestFile, Buffer, Res, BytesWritten);
BytesRead := BytesRead - Res;
end;
end;


Dmitriy Polskoy   (2002-11-14 09:23:00) [49]

2 stikriz (13.11.02 19:49)
Ни какой не бред. Если Res меньше, то остальные байты теряются. Мне надо сделать так, как говорит Digitman © (13.11.02 15:01), но я чето туплю и незнаю как это сделать.

2 s002156Shurik © (14.11.02 01:11)
Это не решает проблемы. Ну буду я получать в таймере, а сокет будет записывать меньше, чем получил. Смотри Digitman © (13.11.02 15:01)


s002156Shurik   (2002-11-14 01:11:00) [50]

Я принимаю так
if Socket.Connected then
begin
if Socket.ReceiveLength>0 then
rsz:=Socket.ReceiveBuf(buf,1024);
end;
понятно дело в цикле вернее в потоке но в данном случае это непринципиально rsz число реально принятых байт проверяю receivelength для того чтобы незапнуться при неожиданном дисконекте если в течении 10 секунд приходят пустые пакеты считаю разрывом по таймауту.
отправляю так:
при коннекте клиента определяю идентификатор сокета
SocHnd:=Socket.SocketHandle;
затем в потоке отсылаю данные через него тыже отсылаеш через конекшенс 0 что будет работать только если один клиент, стемже успехом при коннекте можеш использовать сокетом который передан в ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
и вешать свой сервер на одной задаче. а какже остальные клиенты? или по очереди?
Вобщем я в потоке перебираю все конекшенсы на предмет совпадения идентификатора сокета. и передаю нужному клиенту нужные данные.
for i:=0 to Form1.ServerSocket1.Socket.ActiveConnections-1 do
if Form1.ServerSocket1.Socket.Connections[i].SocketHandle=SoсHnd then
Form1.ServerSocket1.Socket.Connections[i].SendBuf(buf,1024);

простейший способ созданя много потокового сервера файлов это написание объекта на основе TTimer в который при рождении закинуть хандл сокета конекшенса и имя предаваемого файла а дальше запустить OnTime в котором он будет пересылать файл указанным выше способом.
Рождать такой объект нужно при коннекте клиент.
MyTimer:=TMyTimer.create(nil);
MyTimer.FileName:=Socket.recivetext;
MyTimer.SocHnd:=SocHnd:=Socket.SocketHandle;
MyTimer.Interval:=1;
MyTimer.enable:=true;
в OnTime первый раз открыть файл когда он закончится закрыть его
потом сделать дисконнект
for i:=0 to Form1.ServerSocket1.Socket.ActiveConnections-1 do
if Form1.ServerSocket1.Socket.Connections[i].SocketHandle=SoсHnd then
Form1.ServerSocket1.Socket.Connections[i].Disconnect(SocHnd);
и сделать
MyTimer.free;
все.
надеюсь поможет удачи.


stikriz   (2002-11-13 19:49:00) [51]

Res := Socket.ReceiveBuf(Buffer, BytesRead);
if Res < BytesRead then ShowMessage("Error");
BlockWrite(DestFile, Buffer, BytesRead, BytesWritten);
end;

Это полный бред. BytesRead - это для того, чтобы не сделать буфер меньше, чем нужно, а Res - это реально скачанные данные. Часто, но не всегда они равны. И никакой ошибки нет, что Res меньше.

Николай.


Dmitriy Polskoy   (2002-11-13 18:33:00) [52]

2 Digitman © (13.11.02 15:01)
А кусочком кода можно?


Dmitriy Polskoy   (2002-11-13 18:29:00) [53]

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
res: integer;
begin
BytesRead := Socket.ReceiveLength;
Res := Socket.ReceiveBuf(Buffer, BytesRead);
if Res < BytesRead then ShowMessage("Error");
BlockWrite(DestFile, Buffer, BytesRead, BytesWritten);
end;
У меня выскакивает мое сообщенние в ShowMessage. Как исправить ошибку?


F1   (2002-11-13 16:22:00) [54]

Так ведь рядом ветка!


F1   (2002-11-13 16:08:00) [55]

Отсылает меньше, чем принимает??? Опять чудеса!!!
Посмотри SendStream, Digitman его советовал использовать.
А если SendBuf, то посылать, пока в буфере есть место, и обрабатывать OnWrite.
Лучше поищи ветку, где Digitman все расписал, там тема была "Как правильно..." или что-то типа того.


Dmitriy Polskoy   (2002-11-13 16:01:00) [56]

Получается, что отсылает меньше, чем принимает. И как сделать, чтобы ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead) все правильно посылал.


F1   (2002-11-13 15:53:00) [57]

Конечно, проблема именно здесь!!!

ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
Может не послать!!! Он возврвщает количество на самом деле посланных или -1 при ошибке!!!
так что
sum := sum + ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
более реальная цифра, ты ее посмотри, тогда станет ясно, где ошибка!!!


Dmitriy Polskoy   (2002-11-13 15:47:00) [58]

Отправляю так
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
FileName := Socket.ReceiveText;

AssignFile(SrcFile, FileName);
Reset(SrcFile,1);
try
repeat
BlockRead(SrcFile, Buffer, SizeOf(Buffer), BytesRead);
ServerSocket.Socket.Connections[0].SendBuf(Buffer, BytesRead);
sum := sum + bytesread;
label1.Caption := inttostr(sum);
until BytesRead = 0;
finally
CloseFile(SrcFile);
end;
end;

В Label отображается сколько отослал. На клиенте в Label - сколько принял. Значения не равны. Принятый файл действительно равен кол-ву байт, отображенном в label на клиенте, но ясное дело он битый.


F1   (2002-11-13 15:41:00) [59]

А покажи как отправляешь, может быть на самом деле и не отправляется все? Результат SendBuf анализируешь?


Dmitriy Polskoy   (2002-11-13 15:37:00) [60]

Все равно принимаю меньше чем отправляю.
Кстати, помоги найти то, что писал Digitman. Может я что-то не то читал.


Страницы:   1 2 3 4

Наверх

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