![]() ![]() ![]()
|
BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0 |
ソケット通信を行うためのクラスは 3 種類あります。
表 18.2. ソケット通信クラス
| クラス名 | 解説 |
|---|---|
| SFXTCPSocket | TCP ソケット通信のためのクラスです。 |
| SFXSSLSocket | SSL ソケット通信のためのクラスです。 |
| SFXUDPSocket | UDP ソケット通信のためのクラスです。 |
![]() |
mif ファイルの設定 |
|---|---|
mif ファイルの特権レベル設定で「ネットワーク」の項目をオンにします。 | |
TCP ソケット通信は、SFXTCPSocket クラスを使って以下の手順で行います。
例 18.10. NTP サーバーからの時刻取得
// コールバック関数で使うので、SFXTCPSocket クラスのインスタンス _tcp はクラスのメンバ変数として定義する class NetworkTime { private: SFXTCPSocket _tcp; SFXBinaryStreamReader _reader; public: Void Start(Void); // NTP サーバーとの接続を開始する Void Stop(Void); // 接続途中で NTP サーバーとの接続を終了する // コールバック関数の宣言 CALLBACK_DECLARE_SFXTCPSOCKET(OnConnect) CALLBACK_DECLARE_SFXBINARYSTREAMREADER(OnFetch) }; // NTP サーバーに接続を開始する Void NetworkTime::Start(Void) { SFCError error(SFERR_NO_ERROR); // NTP サーバーのアドレスを設定する SFXSocketAddress address("www.example.com:37"); // NTP サーバーとの接続を初期化する if ((error = _tcp.Open()) == SFERR_NO_ERROR) { // NTP サーバーに接続する // ( 接続の完了は、OnConnect 関数に通知される ) if ((error = _tcp.Connect(address, CALLBACK_FUNCTION(OnConnect))) == SFERR_NO_ERROR) { TRACE("connecting..."); } else { // エラーが発生したとき _tcp.Close(); } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき // エラー処理 ... } return; } // 接続途中で NTP サーバーとの接続を終了する場合に呼び出す Void NetworkTime::Stop(Void) { // 終了処理 _reader.Release(); _tcp.Close(); return; } // 接続の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXTCPSOCKET(NetworkTime, OnConnect, error) { if (error == SFERR_NO_ERROR) { // データ受信用ストリームを取得する if ((error = _tcp.GetStreamReader(64, &_reader)) == SFERR_NO_ERROR) { // 4 バイトのデータ受信をする ( データ受信の完了は、OnFetch 関数に通知される ) if ((error = _reader.Fetch(4, CALLBACK_FUNCTION(OnFetch))) == SFERR_NO_ERROR) { TRACE("fetching..."); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _reader.Release(); } } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _tcp.Close(); } return; } // データ受信の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXBINARYSTREAMREADER(NetworkTime, OnFetch, error) { SFXDate date; // 日付クラス UInt32 time; if (error == SFERR_NO_ERROR) { // データをビッグ エンディアンとして読み込む設定をする _reader.SetEndian(SFXBinaryStreamReader::ENDIAN_BIG); // データを UInt32 型として読み込み、time 変数に格納する if ((error = _reader.ReadUInt32(&time)) == SFERR_NO_ERROR) { // time の値を SFXDate インスタンスに設定する date.Set(time); // 受信したデータは 1900 年 1 月 1 日 からの時刻なので調整する date -= SFXDateDuration::Offset19000101(); // 時刻をローカル時刻に変換する date += SFXDateDuration::LocalTimeOffset(); // 時刻を書式に合わせて出力する TRACE("%s", date.Format("YYYY/MM/DD hh:mm:ss").GetCString()); } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき // エラー処理 ... } // 終了処理 _reader.Release(); _tcp.Close(); return; }
SSL ソケット通信は、SFXSSLSocket クラスを使って以下の手順で行います。
例 18.11. SSL ソケット通信
// 太字が TCP と異なる所 // コールバック関数で使うので、SFXSSLSocket クラスのインスタンス _socket はクラスのメンバ変数として定義する class MyClass { private: SFXSSLSocket _socket; SFXAnsiStringStreamWriter _writer; // データ送信用ストリーム SFXAnsiStringStreamReader _reader; // データ受信用トリーム public: Void Start(Void); // コールバック関数 CALLBACK_DECLARE_SFXSSLSOCKET(OnConnect) CALLBACK_DECLARE_SFXSSLSOCKET(OnNegotiate) CALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush) CALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) }; Void MyClass::Start(Void) { SFCError error; SFXSocketAddress host("www.example.com:995"); // TCP サーバーとの接続を初期化する if ((error = _socket.Open()) == SFERR_NO_ERROR) { // ホスト名は自動的に解決される // TCP サーバーに接続する( 接続の完了は、OnConnect 関数に通知される ) error = _socket.Connect(host, CALLBACK_FUNCTION(OnConnect)); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // 接続の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnConnect, error) { if (error == SFERR_NO_ERROR) { // エラーが発生していないとき // ネゴシエートする( サーバーとのネゴシエートに関する通知を受け取ると、OnNegotiate 関数が呼び出される ) error = _socket.Negotiate(CALLBACK_FUNCTION(OnNegotiate)); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // サーバーとのネゴシエートに関する通知を受け取ると呼び出されるコールバック関数 CALLBACK_IMPLEMENT_SFXSSLSOCKET(MyClass, OnNegotiate, error) { static AChar sendingMessage[] = "GET / HTTP/1.0\r\n\r\n"; if (error == SFERR_NO_ERROR) { // データ送信用ストリームを取得する ( バッファ サイズは 1024 ) if ((error = _socket.GetStreamWriter(1024, &_writer)) == SFERR_NO_ERROR) { // データを書き込む if ((error = _writer.Write(sendingMessage, lengthof(sendingMessage))) == SFERR_NO_ERROR) { // 実際にデータを送信する ( データ送信の完了は、OnFlush 関数に通知される ) error = _writer.Flush(CALLBACK_FUNCTION(OnFlush)); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _writer.Release(); } } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // データ送信の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error) { // データ送信を終えると、データ送信用ストリームを解放する _writer.Release(); if (error == SFERR_NO_ERROR) { // データ受信用ストリームを取得する ( バッファ サイズは 1024 ) if ((error = _socket.GetStreamReader(1024, &_reader)) == SFERR_NO_ERROR) { // データを受信する ( データ受信の完了は、OnFetch 関数に通知される ) if ((error = _reader.Fetch(CALLBACK_FUNCTION(OnFetch))) != SFERR_NO_ERROR) { // エラーが発生したとき _reader.Release(); } } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // データ受信の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString receivedString; if (error == SFERR_NO_ERROR) { // ストリームからデータを読み込む _reader > receivedString; // 読み込んだデータを表示する TRACE("%s", receivedString.GetCString()); } // データ受信を終えると、データ受信用ストリームを解放する _reader.Release(); // ソケットをクローズする _socket.Close(); return; }
UDP ソケット通信は、SFXUDPSocket クラスを使って以下の手順で行います。
例 18.12. UDP ソケット通信
// コールバック関数で使うので、SFXUDPSocket クラスのインスタンス _socket はクラスのメンバ変数として定義する class MyClass { private: SFXUDPSocket _socket; public: Void Start(Void); // コールバック関数 CALLBACK_DECLARE_SFXUDPSOCKET(OnBind) CALLBACK_DECLARE_SFXUDPSOCKET(OnSend) CALLBACK_DECLARE_SFXUDPSOCKET(OnReceive) }; Void MyClass::Start(Void) { SFCError error; // UDP ソケットをオープンする if ((error = _socket.Open()) == SFERR_NO_ERROR) { // UDP ソケットをローカル の IP アドレスとポート番号にバインドする OnBind(SFERR_NO_ERROR); } return; } // バインドの完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnBind, error) { SFXSocketAddress address(SFXInetAddress::LoopbackInetAddress(), 1024); // エラーが発生したかどうかチェックする if (error == SFERR_NO_ERROR) { error = _socket.Bind(address); switch (error) { case SFERR_NO_ERROR: // データを非同期に書き込む OnSend(SFERR_NO_ERROR); break; case AEE_NET_WOULDBLOCK: // バインドの完了が通知されるコールバック関数を登録する _socket.ScheduleBind(CALLBACK_FUNCTION(OnBind)); break; } } return; } // データ送信の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnSend, error) { static ACharConst data[] = "udp!"; SFXSocketAddress address(SFXInetAddress::LoopbackInetAddress(), 1024); UInt32 size; // エラーが発生したかどうかチェックする if (error == SFERR_NO_ERROR) { size = sizeof(data) - 1; // データを非同期的に送信する error = _socket.Send(address, data, &size); switch (error) { case SFERR_NO_ERROR: // 指定したサイズのデータが書き込まれたかチェックする // Send 関数は指定したサイズのデータを一度に書き込めないことがある // その場合、ここでは説明の簡略化のためエラーとしている if (size == sizeof(data) - 1) { // データを非同期に読み込む OnReceive(SFERR_NO_ERROR); } else { TRACE("...send failed..."); } break; case AEE_NET_WOULDBLOCK: // データ送信の完了が通知されるコールバック関数を登録する _socket.ScheduleSend(CALLBACK_FUNCTION(OnSend)); break; } } return; } // データ受信の完了が通知されるコールバック関数 CALLBACK_IMPLEMENT_SFXUDPSOCKET(MyClass, OnReceive, error) { SFXSocketAddress socket; SFXBuffer buffer; UInt32 size; // エラーが発生したかどうかチェックする if (error == SFERR_NO_ERROR) { buffer.SetSize(4); size = static_cast<UInt16>(buffer.GetSize()); // 非同期的にデータを受信する switch (_socket.Receive(&socket, buffer.GetBuffer(), &size)) { case SFERR_NO_ERROR: // 指定したサイズのデータが読み込まれたかチェックする // Receive 関数は指定したサイズのデータを一度に読み込めないことがある // その場合、ここでは説明の簡略化のためエラーとしている if (size == buffer.GetSize()) { // 読み込んだデータを表示する buffer.SetSize(buffer.GetSize() + 1); buffer[buffer.GetSize() - 1] = '\0'; TRACE(":%s", SFXAnsiString(buffer).GetCString()); // ソケットをクローズする _socket.Close(); } else { TRACE("...receive failed..."); } break; case AEE_NET_WOULDBLOCK: // データ受信の完了が通知されるコールバック関数を登録する _socket.ScheduleReceive(CALLBACK_FUNCTION(OnReceive)); break; } } return; }
|
Copyright (C) 2002 - 2008 Sophia Cradle Incorporated All Rights Reserved. |
![]() ![]() ![]()
|