こんにちは、ファイルを送受信する方法についてソケットを研究しています。コンポーネント ServerSocket1 を使用してこれを行っています。Google で検索した次のコードがあります。クライアント
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ClientSocket1: TClientSocket;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
Stream: TMemoryStream;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Address:= '127.0.0.1';
ClientSocket1.Port:= 2500;
ClientSocket1.Open;
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ShowMessage('Connected.. Now go load a file!');
end;
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ShowMessage('Did you startup the server? I cannot find it!');
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Size: Integer;
begin
if OpenDialog1.Execute Then
begin
Stream.LoadFromFile(OpenDialog1.Filename);
Size:= Stream.Size;
ClientSocket1.Socket.SendBuf(Size,SizeOf(Size));
ClientSocket1.Socket.SendStream(Stream);
End;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Stream:= TMemoryStream.Create;
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
S: String;
begin
S:= Socket.ReceiveText;
Socket.Close;
ShowMessage('Client: '+S);
end;
end.
サーバー
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp;
type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
SaveDialog1: TSaveDialog;
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
Stream: TMemoryStream;
FSize: Integer;
writing: Boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Port:= 2500;
ServerSocket1.Active:= True;
Stream:= TMemoryStream.Create;
writing:= False;
end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ShowMessage('A client has connected');
end;
procedure TForm1.ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
begin
ShowMessage('I''m listening');
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
BytesReceived: Longint;
CopyBuffer: Pointer; { buffer for copying }
ChunkSize: Integer;
TempSize: Integer;
const
MaxChunkSize: Longint = 8192; { copy in 8K chunks }
begin
If FSize=0 then
begin
If Socket.ReceiveLength>SizeOf(TempSize) then
begin
Socket.ReceiveBuf(TempSize,SizeOf(TempSize));
Stream.SetSize(TempSize);
FSize:= TempSize //Threadsafe code!
End;
End;
If (FSize>0) and not(writing) then
begin
GetMem(CopyBuffer, MaxChunkSize); { allocate the buffer }
writing:= True;
While Socket.ReceiveLength>0 do
Begin
ChunkSize:= Socket.ReceiveLength;
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
BytesReceived:= Socket.ReceiveBuf(CopyBuffer^,ChunkSize);
Stream.Write(CopyBuffer^, BytesReceived); { ...write chunk }
Dec(FSize,BytesReceived);
End;
If FSize=0 then
If SaveDialog1.Execute then
begin
If FileExists(SaveDialog1.Filename) then
DeleteFile(SaveDialog1.Filename);
Stream.SaveToFile(SaveDialog1.Filename);
Socket.SendText('File received!');
Stream.SetSize(0);
FSize:= 0;
End;
FreeMem(CopyBuffer, MaxChunkSize); { allocate the buffer }
Writing:= False;
End;
end;
end.
このコードの問題は、他のファイルを再送信しようとすると、「アドレスでのアクセス違反」または「ストリーム読み取りエラー」としてスローされるため、ファイルを送信できるファイルのみを送信できることです。
このコードを修正するために私ができることと、それぞれの後に複数のファイルを送信できますか?
インディソケットでそれを行う方法の参照はありますか?