落書きノート

ふと自分が気になった事を書いてます

Delphiを試してみたが、課題が残る。

Delphi 10 Seattleのトライアル版を入手し、試してみた。感想としては少々複雑な感じがした。UIはEclipse風。設定個所もそれなりにあるし、ソースコードも少々複雑。文法はPascalをカスタマイズしたような感じ(当たり前か…)。

今回試したのは、ソケットを利用したチャットアプリ。ソケットのパッケージをインストールしてから開発を行う。プロジェクトグループでVCLフォームアプリケーションを二つ作成するのだが、ユニットを使用してもどういうわけか、エラー頻発。UIのファイルメニューから指定してもダメ。製品ドキュメントの通りにやってもダメだった。まあ、自分のやり方が悪いのだろう。

サーバーのプログラムは以下の通り。

unit Server;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Win.ScktComp;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ServerSocket1: TServerSocket;
    Memo1: TMemo;
    Edit1: TEdit;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;  Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  private
    { Private 宣言 }
    var Str: String;
  public
    { Public 宣言 }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses Client;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
     Str:=Edit1.Text;//Take the string (message) sent by the server
     Memo1.Text:=Memo1.Text+'me: '+Str+#13#10;//Adds the message to the memo box
     Edit1.Text:='';//Clears the edit box
//Sends the messages to all clients connected to the server
     for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do
      ServerSocket1.Socket.Connections[i].SendText(str);//Sent
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
   if(ServerSocket1.Active = False)//The button caption is ‘Start’
   then
   begin
      ServerSocket1.Active := True;//Activates the server socket
      Memo1.Text:=Memo1.Text+'Server Started'+#13#10;
      Button2.Caption:='Stop';//Set the button caption
   end
   else//The button caption is ‘Stop’
   begin
      ServerSocket1.Active := False;//Stops the server socket
      Memo1.Text:=Memo1.Text+'Server Stopped'+#13#10;
      Button2.Caption:='Start';
     //If the server is closed, then it cannot send any messages
      Button1.Enabled:=false;//Disables the “Send” button
      Edit1.Enabled:=false;//Disables the edit box
   end;
end;

procedure TForm2.ServerSocket1ClientConnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
  Socket.SendText('Connected');//Sends a message to the client
//If at least a client is connected to the server, then the server can communicate
//Enables the Send button and the edit box
  Button1.Enabled:=true;
  Edit1.Enabled:=true;
end;

procedure TForm2.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
Begin
//The server cannot send messages if there is no client connected to it
  if ServerSocket1.Socket.ActiveConnections-1=0 then
  begin
    Button1.Enabled:=false;
    Edit1.Enabled:=false;
  end;
end;

procedure TForm2.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
Begin
//Read the message received from the client and add it to the memo text
// The client identifier appears in front of the message
  Memo1.Text:=Memo1.Text+'Client'+IntToStr(Socket.SocketHandle)+' :'+Socket.ReceiveText+#13#10;
end;

end.

クライアントのプログラムは以下の通り。

unit Client;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Win.ScktComp;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ClientSocket1: TClientSocket;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ClientSocket1Disconnect(Sender: TObject;  Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private 宣言 }
    var Str: String;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Server;

procedure TForm1.Button1Click(Sender: TObject);
begin
    Str:=Edit1.Text;
    Memo1.Text:=Memo1.Text+'me: '+str+#13#10;
    Edit1.Text:='';//Clears the edit box
    ClientSocket1.Socket.SendText(str);//Send the messages to the server
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//127.0.0.1 is the standard IP address to loop back to your own machine
    ClientSocket1.Address:='127.0.0.1';
    ClientSocket1.Active := True;//Activates the client

 if(ClientSocket1.Socket.Connected=True)
    then
    begin
      str:='Disconnected';
      ClientSocket1.Active := False;//Disconnects the client
      Button2.Caption:='Connect';
    end;
end;


procedure TForm1.ClientSocket1Disconnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
   Memo1.Text:=Memo1.Text+'Disconnect'+#13#10;
   Socket.SendText(str);//Send the “Disconnected” message to the server
//str is set to “Disconnected” when the Disconnect button is pressed
//A client cannot send messages if it is not connected to a server
   Button1.Enabled:=False;
   Edit1.Enabled:=False;
   Button2.Caption:='Connect';
end;

procedure TForm1.ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  ErrorCode:=0;
  ClientSocket1.Active := False;
// This can happen when no active server is started
  Memo1.Text:=Memo1.Text+'No connection found'+#13#10;
end;

procedure TForm2.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
begin
//Reads and displays the message received from the server;
    Memo1.Text:=Memo1.Text+'Server: '+Socket.ReceiveText+#13#10;
end;

end.

ちょっとクライアントとサーバーの作成順序を間違えて逆になってしまった。また一から作り直した方が良さそう。そうじゃないと頭に負荷がかかる。我ながらアホな間違いである。

UIで設定はあらかた済んだはずだが、意図した動作になってくれない。もう少し改善点があるはずなので、もうちょっと考えてみるが、今日はここまで。