Difference between revisions of "Networking/ja"

From Lazarus wiki
Jump to navigationJump to search
Line 22: Line 22:
 
== TCP/IP Protocol ==
 
== TCP/IP Protocol ==
  
== XML ==
+
=== Webserver example ===
  
XML(=The Extensible Markup Language)とは、[http://www.w3.org/ W3C] が推奨する異なるシステム間での情報のやりとりをするための言語です。
+
Bellow there is an example http server written with Synapse and tested in Mac OS X, after changing the synapse source to use a fixed constant $20000 as MSG_NOSIGNAL, because this constant isn't present in the sockets unit in Mac OS X.
これは、情報を保存するために、テキストを基本とする方法です。最近のXHTMLのようなデータ交換方法はWebサービス技術などでもよく使われていますが、それらは、XMLを基礎としています。
 
  
現在、Lazarus上では、XMLをサポートするユニット(群)があります。
+
<delphi>
これらのユニットは、"XMLRead", "XMLWrite" そして "DOM"と呼ばれていますが、これらは、FreePascalCompilerからの、FCLの一部になっています。
+
{
 +
  The Micro Pascal WebServer
  
FCLライブラリはすでにLazarusのデフォルトの検索パスにはいっていますので、それらのユニットをusesするようにすれば、XMLの機能を享受できます。FCLは現在(October / 2005)のところ、文書化されていません。
+
  This is a very simple example webserver implemented with the Synapse library.
ですから、このチュートリアルでは、これらのユニットをつかって、XMLアクセスの方法をご紹介することにしましょう。
 
  
XMLのDOM (Document Object Model)は、異なるシステム間でXMLを利用するための同じようなインターフェースを提供する、標準化されたオブジェクトの集合です。
+
  It works with blocking sockets and a single thread, so it
 +
  can only handle one request at a given time.
  
オブジェクトの標準化といっても、メソッド、プロパティ、オブジェクトの他へのインターフェースパーツのみで、異なる言語や実装といった要素は除去されています。
+
  It will write the headers that it receives from the browser
FCLは現在、完全に[http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/|XML DOM 1.0]をサポートしています.
+
  to the standard output.
  
(訳注:XML,DOMを「完全に」パースする、という実装は、かなり大変なことです。また、異機種間での利用を目的に作られていることに注意しましょう。Lazarusは、クロスコンパイル環境であり、これを標準で持っている事は、とても便利に快適にプログラムが出来ると思われます。日本語がどこまで検証されているのか、というところは、訳からはちょっと分かりませんが...。)
+
  It serves a fixed webpage for the / URI
 +
  For any other URI it will return 504 not found
 +
}
 +
program upserver;
  
 +
{$ifdef fpc}
 +
  {$mode delphi}
 +
{$endif}
  
=== 基本的な例 ===
+
{$apptype console}
  
たとえば、'C:\Programas\teste.xml'といったXMLファイルにアクセスしてみたいとしましょう。
+
uses
このファイルは次のようなものだとします:
+
  Classes, blcksock, sockets, Synautil, SysUtils;
  
<code>
+
{@@
<?xml version="1.0" encoding="ISO-8859-1"?>
+
  Attends a connection. Reads the headers and gives an
<images directory="mydir">
+
  appropriate response
   <imageNode URL="graphic.jpg" title="">
+
}
    <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
+
procedure AttendConnection(ASocket: TTCPBlockSocket);
    <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
+
var
   </imageNode>
+
  timeout: integer;
</images>
+
   s: string;
</code>
+
  method, uri, protocol: string;
 +
  OutputDataString: string;
 +
   ResultCode: integer;
 +
begin
 +
  timeout := 120000;
  
次のコードはノード名をフォーム上のTMemoに書き出す例です。
+
   WriteLn('Received headers+document from browser:');
(usesにXMLRead,XMLWrite,domを追加) 
 
<code>
 
var
 
   Documento: TXMLDocument;
 
  i, j: Integer;
 
begin
 
  Documento := TXMLDocument.Create;
 
  ReadXMLFile(Documento, 'C:\Programas\teste.xml');
 
  Memo.Lines.Clear;
 
  with Documento.DocumentElement.ChildNodes do
 
  begin
 
    for i := 0 to (Count - 1) do
 
    begin
 
      Memo.Lines.Add(Item[i].NodeName + ' ' + Item[i].NodeValue);
 
      for j := 0 to (Item[i].ChildNodes.Count - 1) do
 
      begin
 
        Memo.Lines.Add(Item[i].ChildNodes.Item[j].NodeName + ' '
 
        + Item[i].ChildNodes.Item[j].NodeValue);
 
      end;
 
    end;
 
  end;
 
  Documento.Free;
 
end;
 
</code>
 
  
=== TreeViewにXMLを表現する ===
+
  //read request line
 +
  s := ASocket.RecvString(timeout);
 +
  WriteLn(s);
 +
  method := fetch(s, ' ');
 +
  uri := fetch(s, ' ');
 +
  protocol := fetch(s, ' ');
  
XMLファイルの一般的な利用のひとつに、ツリー形式に構文を解析して、内容を表示することです。 Lazarusの上の「Common Control」タブに、ツリー形式に表示するためのTTreeViewコンポーネントがあります。
+
  //read request headers
 +
  repeat
 +
    s := ASocket.RecvString(Timeout);
 +
    WriteLn(s);
 +
  until s = '';
  
以下での機能は、あらかじめファイルからロードされたか、コードで作られたXMLドキュメントを取得し、コンテンツの内容をTreeViewに表示します。
+
  // Now write the document to the output stream
それぞれのノードのキャプションは、それぞれの(XMLの内容の)最初の属性になるでしょう。
 
  
<pre>
+
  if uri = '/' then
procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
+
  begin
var
+
    // Write the output document to the stream
  iNode: TDOMNode;
+
    OutputDataString :=
 +
      '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
 +
      + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF
 +
      + '<html><h1>Teste</h1></html>' + CRLF;
  
  procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
+
    // Write the headers back to the client
  var
+
    ASocket.SendString('HTTP/1.0 200' + CRLF);
     cNode: TDOMNode;
+
    ASocket.SendString('Content-type: Text/Html' + CRLF);
  begin
+
     ASocket.SendString('Content-length: ' + IntTostr(Length(OutputDataString)) + CRLF);
     if Node = nil then Exit; // Stops if reached a leaf
+
     ASocket.SendString('Connection: close' + CRLF);
      
+
     ASocket.SendString('Date: ' + Rfc822DateTime(now) + CRLF);
     // Adds a node to the tree
+
     ASocket.SendString('Server: Servidor do Felipe usando Synapse' + CRLF);
     TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
+
     ASocket.SendString('' + CRLF);
  
    // Goes to the child node
+
  // if ASocket.lasterror <> 0 then HandleError;
    cNode := Node.ChildNodes.Item[0];
 
  
     // Processes all child nodes
+
     // Write the document back to the browser
     while cNode <> nil do
+
     ASocket.SendString(OutputDataString);
    begin
+
  end
      ProcessNoDe(cNode, TreeNode);
+
   else
      cNode := cNode.NextSibling;
+
     ASocket.SendString('HTTP/1.0 504' + CRLF);
    end;
 
   end;
 
      
 
begin
 
  iNode := XMLDoc.DocumentElement.ChildNodes.Item[0];
 
  while iNode <> nil do
 
  begin
 
    ProcessNode(iNode, nil); // Recursive
 
    iNode := iNode.NextSibling;
 
  end;
 
 
end;
 
end;
</pre>
 
 
=== XML文書を更新する ===
 
まず最初に覚えていただきたいのが、TDOMDocumentがDOMへの「ハンドル」であるということです。
 
あなたはこのクラスのインスタンスを、生成するか、XML文書をロードすることで取得できます。
 
 
一方、通常のオブジェクトのようにノードを生成することはできません。 ノードを作成するためには、TDOMDocumentで提供されている方法、または、他の方法として、ツリー構造の上の正しい場所に設定する方法を使用しなければなりません。 この理由は、ノードがDOMの上の、ある特定のドキュメントによって「所有」されなければならないからです。
 
 
下記は、TDOMDocumentの共通のメソッドです。
 
 
<pre>
 
  function CreateElement(const tagName: DOMString): TDOMElement; virtual;
 
  function CreateTextNode(const data: DOMString): TDOMText;
 
  function CreateCDATASection(const data: DOMString): TDOMCDATASection;
 
    virtual;
 
  function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
 
</pre>
 
 
ここで、TTreeViewに選択された項目の場所に、XML文書の子ノードを挿入する例を示します。
 
[[Networking#Populating a TreeView with XML|XML2Tree function]]を使うことによって、TreeViewはXMLファイルの内容を完全に表現できていなくてはなりません。
 
  
<pre>
 
procedure TForm1.actAddChildNode(Sender: TObject);
 
 
var
 
var
   Posicao: Integer;
+
   ListenerSocket, ConnectionSocket: TTCPBlockSocket;
  NovoNo: TDomNode;
 
 
begin
 
begin
   {*******************************************************************
+
   ListenerSocket := TTCPBlockSocket.Create;
   *  Detects the selected element
+
   ConnectionSocket := TTCPBlockSocket.Create;
  *******************************************************************}
 
  if TreeView1.Selected = nil then Exit;
 
  
   if TreeView1.Selected.Level = 0 then
+
   ListenerSocket.CreateSocket;
   begin
+
  ListenerSocket.setLinger(true,10);
    Posicao := TreeView1.Selected.Index;
+
  ListenerSocket.bind('0.0.0.0','1500');
 +
   ListenerSocket.listen;
  
     NovoNo := XMLDoc.CreateElement('item');
+
  repeat
    TDOMElement(NovoNo).SetAttribute('nome', 'Item');
+
    if ListenerSocket.canread(1000) then
    TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
+
     begin
     XMLDoc.DocumentElement.ChildNodes.Item[Posicao].AppendChild(NovoNo);
+
      ConnectionSocket.Socket := ListenerSocket.accept;
 +
      WriteLn('Attending Connection. Error code (0=Success): ', ConnectionSocket.lasterror);
 +
      AttendConnection(ConnectionSocket);
 +
     end;
 +
  until false;
  
    {*******************************************************************
+
  ListenerSocket.Free;
    *  Updates the TreeView
+
   ConnectionSocket.Free;
    *******************************************************************}
+
end.
    TreeView1.Items.Clear;
+
</delphi>
    XML2Tree(TreeView1, XMLDoc);
 
   end
 
  else if TreeView1.Selected.Level >= 1 then
 
  begin
 
    {*******************************************************************
 
    *  This function only works on the first level of the tree,
 
    *  but can easely modifyed to work for any number of levels
 
    *******************************************************************}
 
  end;
 
end;
 
</pre>
 
  
 
== Webサービス ==
 
== Webサービス ==

Revision as of 03:15, 15 February 2009

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) 한국어 (ko) polski (pl) português (pt) русский (ru) slovenčina (sk) 中文(中国大陆)‎ (zh_CN)


日本語版メニュー
メインページ - Lazarus Documentation日本語版 - 翻訳ノート - 日本語障害情報

このページは、Lazarusでのネットワークプログラムについてのチュートリアルを開始するページになるでしょう。 この記事に、リンクやセクション、ページ、あなたのWikiへのリンクを追加していってください。

(訳注:最初にこの元記事を書いた人はネットワークプログラミングの専門でなく、独学で勉強したことを書いているそうです。日本では、一般的にネットワークプログラミングというと、ソケット、サービス、クライアントサーバー関連の事を指す事が多いのですが、ここでは、XML、およびその派生の仕様によるWEBサービスでのネットワーキングの記事になっていますので、クライアントサーバー、ソケット関連の記事を期待している方は別途TCP/IPソケットコンポーネントや、軽量ネットワークコンポーネントを参照してください。)

このページには、一般的な情報があります。

その他のネットワークのチュートリアル

TCP/IP Protocol

Webserver example

Bellow there is an example http server written with Synapse and tested in Mac OS X, after changing the synapse source to use a fixed constant $20000 as MSG_NOSIGNAL, because this constant isn't present in the sockets unit in Mac OS X.

<delphi> {

 The Micro Pascal WebServer
 This is a very simple example webserver implemented with the Synapse library.
 It works with blocking sockets and a single thread, so it
 can only handle one request at a given time.
 It will write the headers that it receives from the browser
 to the standard output.
 It serves a fixed webpage for the / URI
 For any other URI it will return 504 not found

} program upserver;

{$ifdef fpc}

 {$mode delphi}

{$endif}

{$apptype console}

uses

 Classes, blcksock, sockets, Synautil, SysUtils;

{@@

 Attends a connection. Reads the headers and gives an
 appropriate response

} procedure AttendConnection(ASocket: TTCPBlockSocket); var

 timeout: integer;
 s: string;
 method, uri, protocol: string;
 OutputDataString: string;
 ResultCode: integer;

begin

 timeout := 120000;
 WriteLn('Received headers+document from browser:');
 //read request line
 s := ASocket.RecvString(timeout);
 WriteLn(s);
 method := fetch(s, ' ');
 uri := fetch(s, ' ');
 protocol := fetch(s, ' ');
 //read request headers
 repeat
   s := ASocket.RecvString(Timeout);
   WriteLn(s);
 until s = ;
 // Now write the document to the output stream
 if uri = '/' then
 begin
   // Write the output document to the stream
   OutputDataString :=
     '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
     + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF

+ '<html>

Teste

</html>' + CRLF;

   // Write the headers back to the client
   ASocket.SendString('HTTP/1.0 200' + CRLF);
   ASocket.SendString('Content-type: Text/Html' + CRLF);
   ASocket.SendString('Content-length: ' + IntTostr(Length(OutputDataString)) + CRLF);
   ASocket.SendString('Connection: close' + CRLF);
   ASocket.SendString('Date: ' + Rfc822DateTime(now) + CRLF);
   ASocket.SendString('Server: Servidor do Felipe usando Synapse' + CRLF);
   ASocket.SendString( + CRLF);
 //  if ASocket.lasterror <> 0 then HandleError;
   // Write the document back to the browser
   ASocket.SendString(OutputDataString);
 end
 else
   ASocket.SendString('HTTP/1.0 504' + CRLF);

end;

var

 ListenerSocket, ConnectionSocket: TTCPBlockSocket;

begin

 ListenerSocket := TTCPBlockSocket.Create;
 ConnectionSocket := TTCPBlockSocket.Create;
 ListenerSocket.CreateSocket;
 ListenerSocket.setLinger(true,10);
 ListenerSocket.bind('0.0.0.0','1500');
 ListenerSocket.listen;
 repeat
   if ListenerSocket.canread(1000) then
   begin
     ConnectionSocket.Socket := ListenerSocket.accept;
     WriteLn('Attending Connection. Error code (0=Success): ', ConnectionSocket.lasterror);
     AttendConnection(ConnectionSocket);
   end;
 until false;
 ListenerSocket.Free;
 ConnectionSocket.Free;

end. </delphi>

Webサービス

W3CによるWEBサービスはネットワークの上のマシンから、別のマシンへ、共通的に利用できるように設計されたソフトウェア・システムの名称です。 WEBサービスには、WSDLなど、「機械が処理可能」な形式で記述されているインタフェースがあります。 また、他のシステムは、多くの場合、インタフェースによってSOAPに内包されるメッセージを使用し定められた方法でウェブサービスと対話します。もしくは、RESTによる方法を取るかもしれません。 これらのメッセージは、通常HTTPを使用して伝達され、ウェブ関連の他の規格に関連するXMLから成りたっています。

様々なプログラミング言語で書かれ、様々なプラットホームで動くソフトウェアアプリケーションは、データをおたがいに一つのコンピュータでコミュニケーションを処理します。それと同様の方法を使って、インターネットのようなコンピュータネットワークの上でもコミュニケーションを行うために、WEBサービスを利用することができます。

この相互運用性(例えば、WindowsとLinuxアプリケーションの間など)はオープンスタンダードの運用によるものです。 OASISとW3Cはウェブサービスのアーキテクチャと標準化の策定に責任や権限がある主な委員会です。

ウェブサービス実装間の相互運用性を改良するため、WS-I委員会は、さらに定義する一連のプロフィールを規格の関連の開発をしています。

FPC & Lazarus のWeb Service Toolkit

Web Service Toolkit はFPCとLazarusのWEBサービスのパッケージです。

External Links

XML