Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.05.2009, 21:21   #1
RIO
Форумчанин
 
Аватар для RIO
 
Регистрация: 15.12.2007
Сообщений: 422
По умолчанию Помогите пожалуйста с сокетами :(

Есть код передачи файлов через сокеты . . . Работает он НЕМНОЖКО не коректно, а именно через раз, нажимаю кнопку файл не получает, второй раз нажимаю, получает . . . Помогите пожалуйста !

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WinSock, StdCtrls, ScktComp;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Button2: TButton;
OpenDialog1: TOpenDialog;
ClientSocket1: TClientSocket;
Button3: TButton;
Edit3: TEdit;
SaveDialog1: TSaveDialog;
ServerSocket1: TServerSocket;
procedure FormShow(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
Reciving: Boolean;
DataSize: Integer;
Data: TMemoryStream;
public
end;

var
Form1: TForm1;
Created: Boolean = False;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
MS: TMemoryStream;
begin
ClientSocket1.Address := Edit1.Text;
ClientSocket1.Active := True;
MS := TMemoryStream.Create;
try
MS.LoadFromFile(Edit2.Text);
MS.Position := 0;
ClientSocket1.Socket.SendText(IntTo Str(MS.Size) + #0);
ClientSocket1.Socket.SendStream(MS) ;
except
MS.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Edit2.Text := OpenDialog1.FileName;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
if SaveDialog1.Execute then
Edit3.Text := SaveDialog1.FileName;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Active := True;
end;

procedure TForm1.FormShow(Sender: TObject);
var
WSAData: TWSAData;
P: PHostEnt;
Name: array[0..$FF] of Char;
begin
WSAStartup($0101, WSAData);
GetHostName(Name, $FF);
P := GetHostByName(Name);
Edit1.Text := Inet_Ntoa(PInAddr(P.H_Addr_List^)^) ;
WSACleanup;
end;

procedure TForm1.ServerSocket1ClientRead(Send er: TObject;
Socket: TCustomWinSocket);
var
S, SL: string;
begin

Как я разобрался вся проблема здесь, от клиента в первый раз приходит не размер потока, а целый поток . . . В это вся и проблема . . .



S := Socket.ReceiveText;



if not Reciving then
begin
SetLength(SL, StrLen(PChar(S)) + 1);
StrLCopy(@SL[1], PChar(S), Length(SL) - 1);
DataSize := StrToInt(SL);
Data := TMemoryStream.Create;
Delete(S, 1, Length(SL));
Reciving := True;
end;
try
Data.Write(S[1], Length(S));
if Data.Size = DataSize then
begin
Data.Position := 0;
Data.SaveToFile(Edit3.Text);
Data.Free;
Reciving := False;
Socket.Close;
end;
except
Data.Free;
end;
end;

end.
RIO вне форума Ответить с цитированием
Старый 23.05.2009, 17:54   #2
DOSh
Новичок
Джуниор
 
Регистрация: 23.05.2009
Сообщений: 1
По умолчанию

Проблема в том, что передаются данные не теми кусками, которые были в .SendStream(MS), а так, как решит система. Выходом может стать анализ полученного буфера.
Т.е. передать извесный идентификатор начала сообщения, размер - всегда 4 байта, далее данные. .ReceiveText - в цикл, в принятой строке - поиск идентификатора начала, вычитываем длину, далее в цикле принимаем данные, пока не примется >= длины. Отрезаем от приемного буфера наше сообщение, обрабатывем. В остатке буфера может содержаться начало следующего сообщения.
DOSh вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача файлов по Bluetooth сокетами и не очень) zonch Win Api 6 25.11.2008 17:10
работа с сокетами, содержимое пакетов fire64 C/C++ Сетевое программирование 1 15.03.2008 08:38
Небольшая проблема с сокетами RoamingFire Работа с сетью в Delphi 3 27.02.2008 22:58
Помогите с сокетами delphier Работа с сетью в Delphi 0 19.08.2007 19:03
Работа с сокетами vasilii_terkin Работа с сетью в Delphi 2 13.02.2007 11:08