Форум: "Сети";
Текущий архив: 2002.12.19;
Скачать: [xml.tar.bz2];
ВнизВот как нужно передавать файлы через Socket!!! Найти похожие ветки
← →
F1 (2002-10-22 14:04) [0]Вот все работает на 100%
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ScktComp, ComCtrls;
type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
ServerSocket1: TServerSocket;
SpeedButton1: TSpeedButton;
Edit1: TEdit;
StatusBar1: TStatusBar;
Edit2: TEdit;
ProgressBar1: TProgressBar;
procedure SpeedButton1Click(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Reading:Boolean;
RLength,NLength:Integer;
St:TFileStream;
Number:Integer;
implementation
{$R *.DFM}
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
St:TMemoryStream;
p:^Byte;
Size:Integer;
begin
St:=TMemoryStream.Create;
St.LoadFromFile(Edit1.Text);
Size:=St.Size;
ClientSocket1.Socket.SendBuf(Size, SizeOf(Size));
p:=St.Memory;
Size:=ClientSocket1.Socket.SendBuf(p^, St.Size);
StatusBar1.Panels.Items[0].Text:="Отправлено "+IntToStr(Size);
St.Free;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
S:String;
BufLen:Integer;
Buf:Array of Byte;
begin
if Reading then
begin
BufLen:=Socket.ReceiveLength;
if BufLen>NLength then BufLen:=NLength;
SetLength(Buf, BufLen);
BufLen:=Socket.ReceiveBuf(Buf[0], BufLen);
NLength:=NLength-BufLen;
St.WriteBuffer(Buf[0], BufLen);
if NLength=0 then
begin
StatusBar1.Panels.Items[1].Text:="принято "+IntToStr(RLength-NLength)+" из"+IntToStr(RLength);
St.Free;
Reading:=False;
end;
ProgressBar1.Position:=(RLength-NLength)*100 div RLength;
Application.ProcessMessages;
end else
begin
BufLen:=Socket.ReceiveLength;
if BufLen=0 then Exit;
Reading:=True;
Socket.ReceiveBuf(RLength,SizeOf(RLength));
NLength:=RLength;
BufLen:=Socket.ReceiveLength;
if BufLen>NLength then BufLen:=NLength;
SetLength(Buf, BufLen);
St:=TFileStream.Create(Edit2.Text, fmCreate);
Number:=Number+1;
BufLen:=Socket.ReceiveBuf(Buf[0], BufLen);
NLength:=NLength-BufLen;
St.WriteBuffer(Buf[0], BufLen);
if NLength=0 then
begin
StatusBar1.Panels.Items[1].Text:="Принято "+IntToStr(RLength-NLength)+" из"+IntToStr(RLength);
St.Free;
Reading:=False;
end;
ProgressBar1.Position:=(RLength-NLength)*100 div RLength;
Application.ProcessMessages;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Reading:=False;
end;
end.
← →
Digitman (2002-10-22 14:13) [1]>>Вот все работает на 100%
С чего это ты так уверен ?
Передатчик твой в случае асинхронного режима и размера файла ~8k работать так как ты ожидаешь не будет.
← →
F1 (2002-10-22 14:33) [2]Пробовал передавать файл размером 12 МБайт все работает.
← →
Polevi (2002-10-22 14:39) [3]ты на разных машинах попробуй
← →
Digitman (2002-10-22 14:50) [4]Ты вот это читал ?
см. хэлп на Winsock.Send()- ф-цию
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in a nonblocking I/O mode. On nonblocking stream-oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the local and foreign hosts
То, что это иной раз ожидаемо сработает в пределах лок.хоста, вовсе не говорит о том, что тоже самое будет работать в схеме, когда хосты передатчика и приемника находятся на разных хостах (и в первую очередь - на разных хостах разных подсетей в масштабе глоб.сети)
То, что твой пример не вызвал проблем, говорит о том, что тестировал ты его в рамках одного и того же процесса одного и того же (локального) хоста. В случае распределенных хостов/процессов 100%-но работоспособным сей код не будет.
← →
YouNick (2002-10-22 15:39) [5]2Digitman: А зачем читать документацию????? Это для таких дядек вроде тебя, меня и еще небольшого к-ва здесь присутствующих ;)
Мне просто надоело (давненько ужо) отвечать на подобные вопросы, чего и тебе советую ... ;)
← →
F1 (2002-10-22 15:45) [6]Короче я просто думал, что на Delphi с VCL будет меньше заморочек, чем с API. Лучше заморочиться с API!!! Полезней будет.
← →
Polevi (2002-10-22 16:35) [7]ты абсолютно прав
← →
Digitman (2002-10-22 16:52) [8]>YouNick
Да какой я тебе "дядька"-то ?) Моему либидо кой-кто еще позавидует)))... я только во вкус вхожу еще)))))))))
А отвечать надо :|
Пусть не так часто, но - надо.
Потому как кто-то когда-то ответит мне и, возможно, поможет мне неоценимо....
>F1
Да не нужно "заморочиваться" .. Следует просто с полной серьезностью подходить к поставленной задаче.. Или не браться за нее вообще
А коль ты упомянул "кубики" детского конструктора под названием "VCL", то - опять же - ничто не оправдывает того, что ты не читал вот этого :
For non-blocking sockets, the data is sent to the WinSock DLL which has it"s own internal buffers. If the WinSock can accept additional data, SendBuf returns immediately with the number of bytes queued. If the WinSock internal buffer space is not able to accept the buffer being sent, SendBuf returns -1 and no data is queued at all. In this case, wait a bit for the WinSock to have a chance to send out already-queued data; then try again.
For blocking sockets, SendBuf returns the number of bytes actually written.
К WinsockAPI это как бы отношения мало имеет для тех, кто любит "кубиками" играться)
← →
Malder (2002-10-22 23:09) [9]Откуда такая уверенность, что все сработает на 100% ???
Нету обработчика ошибок, контроля исключительных ситуаций... ничего.
Поразительная самоуверенность.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2002.12.19;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.009 c