HTTP / HTTPS 通信の行う方法
SFXHTTPConnection クラスを利用してHTTP / HTTPS 通信を行います。
// HTTP / HTTPS 通信に必要な SFXHTTPConnection クラスのインスタンス _http は
// クラスのメンバ変数として定義する
class MyClass {
private:
SFXHTTPConnection _http;
SFXAnsiStringStreamReader _reader;
SFXAnsiString _receivedString;
public:
Void Start(Void);
CALLBACK_DECLARE_SFXHTTPCONNECTION(OnConnect)
CALLBACK_DECLARE_SFXANSISTRINGSTREAMREADER(OnFetch)
};
Void MyClass::Start(Void)
{
SFCError error(SFERR_NO_ERROR);
// HTTP 接続の初期化を行う
if ((error = _http.Open()) == SFERR_NO_ERROR) {
// HTTP リクエスト メソッドを "GET" に設定する
// 設定省略時は "GET" となる
_http.SetMethod("GET");
// 接続を開始する
#if 1
// HTTP 接続の場合
if ((error = _http.Connect("http://www.example.com/",
CALLBACK_FUNCTION(OnConnect))) == SFERR_NO_ERROR) {
#else
// HTTPS 接続の場合:
// ※ サーバー証明書が使用するCA証明書が携帯端末に標準搭載
// されていない場合、CA証明書を追加する必要がある
// [下記『関連情報』参照]
//
// 必要に応じて検証モードを設定する
_http.SetTrustMode(SSL_TRUST_MODE_FAIL);
if ((error = _http.Connect("https://www.example.com/",
CALLBACK_FUNCTION(OnConnect))) == SFERR_NO_ERROR) {
#endif
...
}
}
if (error != SFERR_NO_ERROR) {
// エラーが発生したとき
_http.Close();
}
return;
}
// 接続が完了すると呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXHTTPCONNECTION(MyClass, OnConnect, error)
{
SFXPropertyConstPtr header;
SInt16 i;
if (error == SFERR_NO_ERROR) {
// 各種パラメータを表示する
// HTTP ステータス コードを取得する
TRACE("result code = %d", _http.GetResultCode());
// HTTP レスポンス ヘッダーの Content-Length フィールドを取得する
TRACE("content length = %d", _http.GetLength());
// HTTP レスポンス ヘッダーの Content-Type フィールドを取得する
TRACE("content type = %s", _http.GetType().GetCString());
// HTTP レスポンス ヘッダーの Content-Encoding フィールドを取得する
TRACE("content encoding = %s", _http.GetEncoding().GetCString());
// HTTP レスポンス ヘッダーの Date フィールドを取得する
TRACE("date = %s",
_http.GetDate().Format("YYYY/MM/DD hh:mm:ss").GetCString());
// HTTP レスポンス ヘッダーの Expires フィールドを取得する
TRACE("expires = %s",
_http.GetExpires().Format("YYYY/MM/DD hh:mm:ss").GetCString());
// HTTP レスポンス ヘッダーの Last-Modified フィールドを取得する
TRACE("last modified = %s",
_http.GetLastModified().Format("YYYY/MM/DD hh:mm:ss").GetCString());
// HTTP レスポンス ヘッダーを取得する
header = &_http.GetResponseHeader();
// HTTP レスポンス ヘッダーをすべて表示する
for (i = 0; i < header->GetSize(); ++i) {
TRACE("%s: %s", header->GetKey(i).GetCString(),
header->GetValue(i).GetCString());
}
if (_http.GetResultCode() == 200) {
// データ受信用ストリームを取得する
if ((error = _http.GetStreamReader(1024, &_reader))
== SFERR_NO_ERROR) {
// フェッチ(データ受信)する
// データ受信が完了すると、OnFetch 関数に通知される
if ((error = _reader.Fetch(CALLBACK_FUNCTION(OnFetch)))
== SFERR_NO_ERROR) {
...
}
}
}
else {
error = SFERR_INVALID_STATE;
}
}
if (error != SFERR_NO_ERROR) {
// エラーが発生したとき
_http.Close();
}
return;
}
// フェッチ(データ受信)が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXANSISTRINGSTREAMREADER(MyClass, OnFetch, error)
{
SFXAnsiString string;
if (error == SFERR_NO_ERROR) {
// データ受信用ストリームからデータを取得する
if ((error = _reader.ReadSFXAnsiString(&string)) == SFERR_NO_ERROR) {
// 断片化されたデータを結合する
if ((error = _receivedString.Add(string)) == SFERR_NO_ERROR) {
// 残りのデータをチェックする
if (_reader.Ends()) {
// すべてのデータが受信できたので表示する
TRACE("--------");
TRACE("%s", _receivedString.GetCString());
TRACE("--------");
// 明示的にリソースを解放する
_reader.Release();
_http.Close();
}
else {
// フェッチ(データ受信)する
// データ受信が完了すると、OnFetch 関数に通知される
error = _reader.Fetch(CALLBACK_FUNCTION(OnFetch));
}
}
}
}
if (error != SFERR_NO_ERROR) {
// エラーが発生したとき
_reader.Release();
_http.Close();
}
return;
独自にルート証明書を追加して https 通信を行う方法
BREW 3.1 端末でHTTPS 通信を高速化する方法
QUALCOMM 社の情報によりますと、
BREW3.1.2 以前の実装では、ISSL インターフェースが過剰にパケットを細分化するため HTTPS 通信のパフォーマンスが劣化するらしいです。(参照:関連情報)
この問題を解決するためには、
下記のように SFXHTTPConnection クラスを開いてから接続するまでの間に、
SFXHTTPConnection クラスが内部で保持する SFBWeb インスタンスを取得して、この問題が解決されている ISSL インターフェースのクラス ID「AEECLSID_SSL_101」を渡すようにします。
なお、関連情報には、
『本機能は利用例が少なく、十全な評価がされていないため、使用のリスクは御社でご判断下さい』とあります。
#include "AEESSL_WEBOPT_CLASSID.h"
#include "ISSL.bid"
_http.Open()
SFBWebOpts webopts = SFBWebOpts::NewInstance(&error);
WebOpt opt[2];
opt[0].nId = WEBOPT_SSL_CLASSID;
opt[0].pVal = (VoidPtr)AEECLSID_SSL_101;
opt[1].nId = WEBOPT_END;
opt[1].pVal = null;
webopts->AddOpt(opt);
SFBWebSmp web = _http.GetSFBWeb();
web->AddOpt(opt);
_http.Connect(url, XALLBACK_INTERNAL(OnConnect));
※ 接続時間が短縮されたもののフェッチに時間がかかる場合は、ストリームリーダーのバッファサイズを小さくしてみてください。たとえば、4096バイト(デフォルト)を2048バイトにすることで高速化された例があります。
SSL メール受信をする
SFXPOP3Receiver クラスの SFXPOP3Receiver::SetSSLMode 、 SFXPOP3Receiver::SetTrustMode を使って、SSL メール受信を行います。
class MyClass {
private:
SFXPOP3Receiver _receiver;
CALLBACK_DECLARE_SFXPOP3RECEIVER(POP3Callback)
public:
Void Start(Void);
};
// 太字の部分を追加
Void MyClass::Start(Void)
{
// ユーザー名とパスワードを設定する
_receiver.SetAccount("user", "password");
// POP3 サーバーの IP アドレスとポート番号を指定する
// ( ドメインは自動解決される )
_receiver.SetServer(SFXSocketAddress("pop3server.example.com:995"));
// SSL メール受信の設定
_receiver.SetSSLMode(true); // SSL 接続モードの設定
// 証明書の検証モードの設定
_receiver.SetTrustMode(SSL_TRUST_MODE_FAIL);
// メールを受信する。受信が完了すると、POP3Callback 関数が呼び出される
if ((error = _receiver.Receive(CALLBACK_FUNCTION(POP3Callback)))
!= SFERR_NO_ERROR) {
// error が SFERR_NO_ERROR でない場合はコールバックが戻らないので、
// ここでエラー処理をする
}
}
// メール受信が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXPOP3RECEIVER(MyClass, POP3Callback, error)
{
SInt32 i;
if (error == SFERR_NO_ERROR) {
//受信に成功した場合
// 受信したメールの配列 ( SFXArray ) を取得する
const SFXArray<SFXPOP3Receiver::MailInfoPtr>& mailArray =
receiver.GetReceivedMailArray();
// メール数を表示する
TRACE("received %d mails", mailArray.GetSize());
for (i = 0; i < mailArray.GetSize() ; i++) {
SFXPOP3Receiver::MailInfoPtr minfo = mailArray[i];
// 左から順に、メール サイズ、UIDL、メール ヘッダーとメール本文
// を含む メール メッセージを含むメール本体を表示する
TRACE("%d, %s, %s", minfo->size,
minfo->uidl.GetCString(),
minfo->mail.GetCString());
}
}
}
SSL メール送信をする
SFXSMTPSender クラスの SFXSMTPSender::SetSSLMode 、 SFXSMTPSender::SetTrustMode 、 SFXSMTPSender::SetAuthorization を使って、SSL メール送信を行います。
class MyClass {
private:
SFXSMTPSender _sender;
CALLBACK_DECLARE_SFXSMTPSENDER(SMTPCallback)
public:
Void Start(Void);
};
// 太字の部分を追加
Void MyClass::Start(Void)
{
SFCError error;
SFXMailMessage message;
// メール ヘッダーに From フィールドを設定する
message.SetFromField("fromaddress@example.com");
// メール ヘッダーに To フィールドを追加する
message.AddToField("toaddress1@example.com");
message.AddToField("toaddress2@example.com");
// メール ヘッダーに Subject フィールドを設定する
message.SetSubjectField("Mail Subject");
// メール メッセージの本文を設定する
message.SetBody("Mail test\r\nThis mail is sent by SFXSMTPSender.\r\n");
// SMTP サーバーの IP アドレスとポート番号を指定する
// ( ドメインは自動解決される )
_sender.SetServer(SFXSocketAddress("smtpserver.example.com:465"));
// SSL メール送信の設定
_sender.SetSSLMode(true); // SSL 接続モードの設定
// 証明書の検証モードの設定
_sender.SetTrustMode(SSL_TRUST_MODE_FAIL);
// SMTP 認証モードの設定
_sender.SetAuthorization(AUTH_CRAM_MD5,"username","password");
// メールを送信する。送信が完了すると SMTPCallback 関数が呼び出される
if ((error = _sender.SendMessage(&message,
CALLBACK_FUNCTION(SMTPCallback))) != SFERR_NO_ERROR) {
// error が SFERR_NO_ERROR でない場合はコールバックが戻らないので、
// ここでエラー処理をする
}
}
// メール送信が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXSMTPSENDER(MyClass, SMTPCallback, error)
{
if (error == SFERR_NO_ERROR) {
TRACE("メールを送信しました。");
}
else {
TRACE("メール送信に失敗しました。 %d", error);
}
}
POP3 メール受信をする
SFXPOP3Receiver クラスを使ってメール受信を行います。
class MyClass {
private:
SFXPOP3Receiver _receiver;
CALLBACK_DECLARE_SFXPOP3RECEIVER(POP3Callback)
public:
Void Start(Void);
};
Void MyClass::Start(Void)
{
// ユーザー名とパスワードを設定する
_receiver.SetAccount("user", "password");
// POP3 サーバーの IP アドレスとポート番号を指定する
// ( ドメインは自動解決される )
_receiver.SetServer(SFXSocketAddress("pop3server.example.com:110"));
// メールを受信する。受信が完了すると、POP3Callback 関数が呼び出される
if ((error = _receiver.Receive(CALLBACK_FUNCTION(POP3Callback)))
!= SFERR_NO_ERROR) {
// error が SFERR_NO_ERROR でない場合はコールバックが戻らないので、
// ここでエラー処理をする
}
}
// メール受信が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXPOP3RECEIVER(MyClass, POP3Callback, error)
{
SInt32 i;
if (error == SFERR_NO_ERROR) {
//受信に成功した場合
// 受信したメールの配列 ( SFXArray ) を取得する
const SFXArray<SFXPOP3Receiver::MailInfoPtr>& mailArray =
receiver.GetReceivedMailArray();
// メール数を表示する
TRACE("received %d mails", mailArray.GetSize());
for (i = 0; i < mailArray.GetSize() ; i++) {
SFXPOP3Receiver::MailInfoPtr minfo = mailArray[i];
// 左から順に、メール サイズ、UIDL、メール ヘッダーとメール本文を含む
// メール メッセージを表示する
TRACE("%d, %s, %s", minfo->size, minfo->uidl.GetCString(), minfo->mail.GetCString());
}
}
}
SMTP メール送信をする
SFXSMTPSender クラスを使ってメール送信を行います。
class MyClass {
private:
SFXSMTPSender _sender;
CALLBACK_DECLARE_SFXSMTPSENDER(SMTPCallback)
public:
Void Start(Void);
};
Void MyClass::Start(Void)
{
SFCError error;
SFXMailMessage message;
// メール ヘッダーに From フィールドを設定する
message.SetFromField("fromaddress@example.com");
// メール ヘッダーに To アドレスを追加する
message.AddToField("toaddress1@example.com");
message.AddToField("toaddress2@example.com");
// メール ヘッダーに Subject フィールドを設定する
message.SetSubjectField("Mail Subject");
// メール メッセージの本文を設定する
message.SetBody("Mail test\r\nThis mail is sent by SFXSMTPSender.\r\n");
// SMTP サーバーの IP アドレスとポート番号を指定する
// ( ドメインは自動解決される )
_sender.SetServer(SFXSocketAddress("smtpserver.example.com:25"));
// メールを送信する。送信が完了すると SMTPCallback 関数が呼び出される
if ((error = _sender.SendMessage(&message,
CALLBACK_FUNCTION(SMTPCallback))) != SFERR_NO_ERROR) {
// error が SFERR_NO_ERROR でない場合はコールバックが戻らないので、
// ここでエラー処理をする
}
}
// メール送信が完了したときに呼び出されるコールバック関数
CALLBACK_IMPLEMENT_SFXSMTPSENDER(MyClass, SMTPCallback, error)
{
if (error == SFERR_NO_ERROR) {
TRACE("メールを送信しました。");
}
else {
TRACE("メール送信に失敗しました。 %d", error);
}
}
UDP ソケット通信を行う方法
SFXUDPSocket クラスを利用して UDP ソケット通信を行います。
// 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;
// ソケットを開く
if ((error = _socket.Open()) == SFERR_NO_ERROR) {
// ソケットをローカル の 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(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;
}
SSL ソケット通信を行う方法
SFXSSLSocket クラスを利用して SSL ソケット通信を行います。
// SSL ソケット通信に必要な 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 サーバーに接続する
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) {
// エラーが発生していないとき
// ネゴシエートする
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) {
// バッファからデータを receivedString 変数に読み込む
_reader >> receivedString;
// 応答を表示する
TRACE("%s", receivedString.GetCString());
}
// 受信が終わったのでデータ受信用ストリームを解放する
_reader.Release();
// ソケットを閉じる
_socket.Close();
return;
}
※ 日本ベリサイン社の ssltest7.verisign.co.jp:443 または rollovertest2.verisign.co.jp:443 のサーバーにて SSL 接続テストが利用可能です。
TCP ソケット通信を行う方法
SFXTCPSocket クラスを利用して、TCP ソケット通信を行います。
// TCP ソケット 通信に必要な 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 サーバーに接続する
if ((error = _tcp.Connect(address,
CALLBACK_FUNCTION(OnConnect))) == SFERR_NO_ERROR) {
...
}
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) {
...
}
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) {
// 日付クラスに取得した時刻 ( 秒 ) を設定する
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;
}
ホスト名からIPアドレスを取得する
バージョン 4.0 以降
ホスト名からIPアドレスを取得するには SFXSocketAddress クラスの SFXSocketAddress::Resolve 関数を使用します。
この関数が呼び出されるとネットワーク通信を行い、通信完了後にコールバックとして
登録された関数が呼び出されます。
SFMTYPEDEFCLASS(MyClass)
class MyClass {
private:
SFXSocketAddress _address;
public:
Void Function(Void);
CALLBACK_DECLARE_SFXSOCKETADDRESS(ResolveCallback)
};
Void MyClass::Function(Void)
{
_address.Set("www.example.com:80");
// ホスト名を解決する (要エラーチェック)
_address.Resolve(CALLBACK_FUNCTION(ResolveCallback));
}
// ホスト名が解決できたときに呼び出されるコールバック
CALLBACK_IMPLEMENT_SFXSOCKETADDRESS(MyClass, ResolveCallback, error)
{
SInt32 i;
for (i = 0; i < _address.GetCount(); ++i) {
SFXAnsiString string = _address.GetIP(i); // IP アドレスを文字列として取得
}
}
バージョン 3.0
ホスト名からIPアドレスを取得するには SFUHostResolver クラスを使用します。
この関数が呼び出されるとネットワーク通信を行い、通信完了後にコールバックとして
登録された関数が呼び出されます。
SFMTYPEDEFCLASS(MyClass)
class MyClass {
private:
SFUHostResolverPtr _resolver;
public:
Void Function(Void);
static Void NotifyResolvingSHP(SFCError error, SFUHostResolverRef resolver,
VoidPtr data);
Void NotifyResolving(SFCError error, SFUHostResolverRef resolver);
};
Void MyClass::Function(Void) // この関数の中でIPアドレスを取得する
{
// コンストラクタでコールバック関数を取得
_resolver = new SFUHostResolver(NotifyResolvingSHP, this);
// ホスト名を解決 (要エラーチェック)
_resolver->Resolve("www.example.com");
}
// ホスト名が解決できたときに呼び出されるコールバック
static Void MyClass::NotifyResolvingSHP(SFCError error, SFUHostResolverRef resolver,
VoidPtr data)
{
static_cast(data)->NotifyResolving(error, resolver);
}
// コールバックの実装
Void MyClass::NotifyResolving(SFCError error, SFUHostResolverRef resolver)
{
SInt32 i;
// GetResolvedCount 関数で取得したIPアドレスの個数を取得
for (i = 0; i < resolver.GetResolvedCount(); ++i) {
// GetResolvedAddress でIPアドレスを取得し、SFUIPEndpoint 型に変換
SFUIPEndpoint address(resolver.GetResolvedAddress(i));
}
delete &resolver;
}
参照 SFXSocketAddress::Set | SFXSocketAddress::Resolve |
SFXSocketAddress::GetCount | SFXSocketAddress::GetIP