SophiaFramework UNIVERSE 5.3 |
SFXTCPSocket クラスは、 TCP クライアントと TCP サーバーを実装する機能を提供します。
このクラスでは、ストリームを利用したデータ送受信が可能です。
ストリームを利用しない場合は SFXTCPSocket::Write / SFXTCPSocket::Read 関数を使用してデータを送受信します。
■ SFXTCPSocket クラスの使用手順(TCP クライアントの実装)
例 18.4. ストリームを使用した TCP ソケット通信
// コールバック関数で使用するので、_socket はクラスのメンバ変数として定義する class MyClass { private: SFXTCPSocket _socket; // SFXTCPSocket インスタンス SFXAnsiStringStreamReader _reader; // データ受信用ストリーム SFXAnsiStringStreamWriter _writer; // データ送信用ストリーム public: Void Start(Void); XALLBACK_DECLARE_SFXTCPSOCKET(OnConnect) XALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch) XALLBACK_DECLARE_SFXANSISTRINGSTREAMWRITER(OnFlush) }; Void MyClass::Start(Void) { SFCError error; SFXSocketAddress host("www.example.com:995"); // ソケットを開く if ((error = _socket.Open()) == SFERR_NO_ERROR) { // サーバーに接続する // ※1. 接続要求の結果は、OnConnect 関数に通知される // ※2. ホスト名(host)は自動的に解決される error = _socket.Connect(host, XALLBACK_INTERNAL(OnConnect)); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // 接続要求の結果が通知されるコールバック関数 XALLBACK_IMPLEMENT_SFXTCPSOCKET(MyClass, OnConnect, error) { // 送信する文字列 static AChar message[] = "GET / HTTP/1.0\r\n\r\n"; if (error == SFERR_NO_ERROR) { // データ送信用ストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 if ((error = _socket.GetStreamWriter(&_writer)) == SFERR_NO_ERROR) { // message 変数からストリームバッファにデータを書き込む // ※ message 変数のサイズに合わせてバッファは自動的に拡張される if ((error = _writer.Write(message, lengthof(message))) == SFERR_NO_ERROR) { // フラッシュを行う: 実際にストリームバッファからソケットにデータを送信する // ※1. データ送信(フラッシュ)の結果は、OnFlush 関数に通知される // ※2. 可変長バッファストリームの場合、1 回の Flush 関数呼び出しでデータ送信は完了する error = _writer.Flush(XALLBACK_INTERNAL(OnFlush)); } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _writer.Release(); } } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // データ送信(フラッシュ)の結果が通知されるコールバック関数 XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMWRITER(MyClass, OnFlush, error) { // 送信が終わったのでデータ送信用ストリームを解放する _writer.Release(); if (error == SFERR_NO_ERROR) { // データ受信用ストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 if ((error = _socket.GetStreamReader(&_reader)) == SFERR_NO_ERROR) { // フェッチを行う: 実際にソケットからストリームバッファにデータを受信する // ※1. データ受信(フェッチ)の結果は、OnFetch 関数に通知される // ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しでデータ受信は完了する // ※3. 受信するデータのサイズに合わせてバッファは自動的に拡張される if ((error = _reader.Fetch(XALLBACK_INTERNAL(OnFetch))) != SFERR_NO_ERROR) { // エラーが発生したとき _reader.Release(); } } } if (error != SFERR_NO_ERROR) { // エラーが発生したとき _socket.Close(); } return; } // データ受信(フェッチ)の結果が通知されるコールバック関数 XALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error) { SFXAnsiString string; if (error == SFERR_NO_ERROR) { // ストリームバッファから string 変数にデータを読み込む _reader >> string; // string 変数の内容をデバッグウィンドウに表示する TRACE("%s", string.GetCString()); } // 受信が終わったのでデータ受信用ストリームを解放する _reader.Release(); // ソケットを閉じる _socket.Close(); return; }
可変長バッファストリームによる TCP ソケット通信 | |
---|---|
ストリームにはバッファがあります。 SFXTCPSocket::GetStreamReader / SFXTCPSocket::GetStreamWriter 関数で size 引数を指定せずにデータ送受信用ストリームを取得しているので、 可変長バッファが使用されます。 このため、ストリームバッファに送受信する全データと同じサイズまで拡張されます。 SFXAnsiStringStreamWriter::WriteSFXAnsiString 関数は、 string 変数のデータをストリームバッファに書き込みます。 SFXAnsiStringStreamReader::ReadSFXAnsiString 関数は、 ストリームバッファからデータを読み込み、string 変数に格納します。 SFXStreamWriter::Flush 関数は、 ストリームバッファ内のデータを TCP ソケット通信ネットワークに送信します。 SFXStreamReader::Fetch 関数は、 TCP ソケット通信ネットワークからデータを受信し、ストリームバッファに読み込みます。 |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |