OneDeath
asked on
HELP ScktComp File Transfer
for some reason the file received is not a valid file (either. doc . jpg .exe)
here is my code:
http://rapidshare.com/files/249987383/File_Transfer.rar.html
here is my code:
http://rapidshare.com/files/249987383/File_Transfer.rar.html
client
unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
type
TForm1 = class(TForm)
Button1: TButton;
ClientSocket1: TClientSocket;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.Host:= Edit1.Text;
ClientSocket1.Port:= StrToInt(Edit2.Text);
ClientSocket1.Open;
end;
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode:= 0;
end;
procedure ReadData(Socket: TCustomWinSocket; nSize: Integer);
var
Buffer: array[0..1023] of Byte;
read, currRead, buffSize: Integer;
Stream: TMemoryStream;
begin
Stream:= TMemoryStream.Create;
buffSize := SizeOf(Buffer);
try
Stream.Clear;
Stream.SetSize(nSize);
read := 0;
while (read < nSize) and (Socket.Connected) do
begin
if (nSize - read) >= buffSize then
currRead := buffSize
else
currRead := (nSize - read);
Socket.ReceiveBuf(buffer, currRead);
Stream.WriteBuffer(buffer, currRead);
read := read + currRead;
end;
Stream.Position := 0;
Stream.SaveToFile('calc.exe');
Stream.Free;
except
end;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
Data: String;
Size: Integer;
begin
Data:= Socket.ReceiveText;
if Copy(Data, 1, 4) = 'FILE' then
begin
Caption:= Data;
Delete(Data, 1, Pos('|', Data));
Size := StrToInt(Copy(Data, 1, Pos('|', Data) - 1));
Delete(Data, 1, Pos('|', Data));
if Size > 0 then ReadData(Socket, Size);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText('FILE');
end;
end.
server
//www.opensc.ws 4ever! :P
{====================================================================
An example of how to make a formless server for a very small filesize.
by Turkey
=====================================================================}
program formless;
{$APPTYPE CONSOLE}
uses
scktcomp, classes, sysutils, windows;
Type
TMyApp = Class(TObject)
Public
Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
End;
var
MyApp: TMyApp;
Server: TServerSocket;
Msg : Tmsg;
TimerHandle:WORD;
Stream: TMemoryStream;
function SendData(Socket: TCustomWinsocket; Stream: TMemoryStream; Command: string): Boolean;
var
Buffer: array[0..1023] of Byte;
Read, CurrRead, BuffSize: Integer;
begin
try
Socket.SendText(Command + '|' + IntToStr(Stream.Size) + '|');
buffSize := SizeOf(Buffer);
read := 0;
while (read < Stream.Size) and Socket.Connected do
begin
if (Stream.Size - read) >= buffSize then
CurrRead := BuffSize
else
CurrRead := (Stream.Size - Read);
Stream.ReadBuffer(Buffer, CurrRead);
Socket.SendBuf(Buffer, CurrRead);
Read := Read + CurrRead;
end;
Result := True;
except
Result := False;
end;
end;
Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket);
Begin
WriteLn('Connected');
End;
Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket);
Begin
WriteLn('Disconnected');
End;
Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket);
Var
Data: String;
Begin
Data:= Socket.ReceiveText;
if Data = 'FILE' then
begin
Stream := TMemoryStream.Create;
Stream.LoadFromFile('calc.exe');
Stream.Position:= 0;
if SendData(Socket, Stream, 'FILE') then WriteLn('File Sended');
end;
end;
//=======Timer=========
procedure Timer(Wnd:HWnd;Msg,TimerID,dwTime:DWORD);stdcall;
begin
//Code for your Timer Goes here
end;
procedure StartTimer(Interval:DWORD);
begin
TimerHandle:=SetTimer(0,0,Interval,@Timer);
end;
//======Timer==========
begin
MyApp := TMyApp.Create;
//Create the socket.
Server := TServerSocket.Create(nil);
Server.OnClientConnect := MyApp.Connect;
Server.OnClientDisconnect := MyApp.Disconnect;
Server.OnClientRead := MyApp.Receive;
//Choose the socket port here.
Server.Port := 669;
//Activate the socket.
Server.Active := True;
//Code to start the timer, the number is the timer interval.
StartTimer(1000);
//this code keeps the server open, stoping it from closing.
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
ASKER
no, it cant be, because i try only sending the file (without commands) and the problem persists, can someone fix for me?
What is the code you are using when you send the file without parameters? Also what is the size (bytes) of the original file and the size (bytes) of the destination file after the transfer?
ASKER
this is the code without the commands, the filesize of calc.exe is 115200 bytes
client
unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
type
TForm1 = class(TForm)
Button1: TButton;
ClientSocket1: TClientSocket;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.Host:= Edit1.Text;
ClientSocket1.Port:= StrToInt(Edit2.Text);
ClientSocket1.Open;
end;
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode:= 0;
end;
procedure ReadData(Socket: TCustomWinSocket; nSize: Integer);
var
Buffer: array[0..1023] of Byte;
read, currRead, buffSize: Integer;
Stream: TMemoryStream;
begin
Stream:= TMemoryStream.Create;
buffSize := SizeOf(Buffer);
try
Stream.Clear;
Stream.SetSize(nSize);
read := 0;
while (read < nSize) and (Socket.Connected) do
begin
if (nSize - read) >= buffSize then
currRead := buffSize
else
currRead := (nSize - read);
Socket.ReceiveBuf(buffer, currRead);
Stream.WriteBuffer(buffer, currRead);
read := read + currRead;
end;
Stream.Position := 0;
Stream.SaveToFile('calc.exe');
Stream.Free;
except
end;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
ReadData(Socket, 115200);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText('FILE');
end;
end.
server
//www.opensc.ws 4ever! :P
{====================================================================
An example of how to make a formless server for a very small filesize.
by Turkey
=====================================================================}
program formless;
{$APPTYPE CONSOLE}
uses
scktcomp, classes, sysutils, windows;
Type
TMyApp = Class(TObject)
Public
Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
End;
var
MyApp: TMyApp;
Server: TServerSocket;
Msg : Tmsg;
TimerHandle:WORD;
Stream: TMemoryStream;
function SendData(Socket: TCustomWinsocket; Stream: TMemoryStream): Boolean;
var
Buffer: array[0..1023] of Byte;
Read, CurrRead, BuffSize: Integer;
begin
try
buffSize := SizeOf(Buffer);
read := 0;
while (read < Stream.Size) and Socket.Connected do
begin
if (Stream.Size - read) >= buffSize then
CurrRead := BuffSize
else
CurrRead := (Stream.Size - Read);
Stream.ReadBuffer(Buffer, CurrRead);
Socket.SendBuf(Buffer, CurrRead);
Read := Read + CurrRead;
end;
Result := True;
except
Result := False;
end;
end;
Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket);
Begin
WriteLn('Connected');
End;
Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket);
Begin
WriteLn('Disconnected');
End;
Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket);
Var
Data: String;
Begin
Data:= Socket.ReceiveText;
if Data = 'FILE' then
begin
Stream := TMemoryStream.Create;
Stream.LoadFromFile('calc.exe');
Stream.Position:= 0;
if SendData(Socket, Stream) then WriteLn('File Sended');
end;
end;
//=======Timer=========
procedure Timer(Wnd:HWnd;Msg,TimerID,dwTime:DWORD);stdcall;
begin
//Code for your Timer Goes here
end;
procedure StartTimer(Interval:DWORD);
begin
TimerHandle:=SetTimer(0,0,Interval,@Timer);
end;
//======Timer==========
begin
MyApp := TMyApp.Create;
//Create the socket.
Server := TServerSocket.Create(nil);
Server.OnClientConnect := MyApp.Connect;
Server.OnClientDisconnect := MyApp.Disconnect;
Server.OnClientRead := MyApp.Receive;
//Choose the socket port here.
Server.Port := 669;
//Activate the socket.
Server.Active := True;
//Code to start the timer, the number is the timer interval.
StartTimer(1000);
//this code keeps the server open, stoping it from closing.
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.
For stream it is recommended that Read and Write is used instead of ReadBuffer and WriteBuffer (the latter are for internal use, parameters are the same).
There are two problems with this example.
1) ClientSocket1Read may be triggered multiple times (even if there is no data to be read). Call ReadData right after yourequest the file instead. like:
procedure TForm1.Button1Click(Sender : TObject);
begin
ClientSocket1.Socket.SendT ext('FILE' );
ReadData(ClientSocket1.Soc ket, 115200);
end;
2) Socket.ReceiveBuf(buffer, currRead); will only read the number of bytes that are available, if currRead bytes are not available, the function will return the number of bytes actually read, replace line with:
currRead := Socket.ReceiveBuf(buffer, currRead);
There are two problems with this example.
1) ClientSocket1Read may be triggered multiple times (even if there is no data to be read). Call ReadData right after yourequest the file instead. like:
procedure TForm1.Button1Click(Sender
begin
ClientSocket1.Socket.SendT
ReadData(ClientSocket1.Soc
end;
2) Socket.ReceiveBuf(buffer, currRead); will only read the number of bytes that are available, if currRead bytes are not available, the function will return the number of bytes actually read, replace line with:
currRead := Socket.ReceiveBuf(buffer, currRead);
NVM the first sentence about re read/write (my misstake when I read the docs it said it was used internally, nothing about not using them). Rest should be ok (I tested it).
ASKER
I did step by step as you told me to but it does not work :|
can you upload full source to some site?
can you upload full source to some site?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks very much dude =)
you read FILE|size|....
using
Data:= Socket.ReceiveText;
Check the contents of Data at this point, does it also contain part of the file you are transferring?