CSocketFile クラス
更新 : 2007 年 11 月
Windows ソケットを使ったネットワーク間でのデータの送受信に使われる CFile オブジェクトです。
class CSocketFile : public CFile
解説
この目的のために、CSocketFile オブジェクトを CSocket オブジェクトに関連付けることができます。また、MFC のシリアル化を使って簡単にデータの送受信を行うために、CSocketFile オブジェクトを CArchive オブジェクトに関連付けることもできます。通常はそのようにします。
データをシリアル化 (送信) するには、データをアーカイブに挿入します。アーカイブは CSocketFile のメンバ関数を呼び出し、データを CSocket オブジェクトに書き込みます。データをデシリアル化 (受信) するには、アーカイブからデータを取り出します。この結果アーカイブは、CSocketFile のメンバ関数を呼び出し、CSocket オブジェクトからデータを読み取ります。
ヒント : |
---|
ここで説明した CSocketFile の使い方以外に、基本クラスの CFile と同様に、CSocketFile をスタンドアロン ファイル オブジェクトとして使用できます。また、CSocketFile をアーカイブ ベースの MFC のシリアル化関数と組み合わせて使うことができます。CSocketFile では、CFile のすべての機能はサポートされていないため、いくつかの既定の MFC シリアル化関数は CSocketFile では互換性がありません。CEditView クラスなどがその例です。CEditView::SerializeRaw を使って、CSocketFile オブジェクトに関連付けられた CArchive オブジェクトを経由して CEditView データをシリアル化しないでください。代わりに CEditView::Serialize を使います。SerializeRaw 関数は、ファイル オブジェクトが Seek のような関数を持つことを想定していますが、CSocketFile はそのような関数を持っていません。 |
CArchive を CSocketFile および CSocket と共に使用した場合、CSocket::Receive が、要求するバイト数を待機するループ (PumpMessages(FD_READ) による) に入る場合があります。これは、Windows ソケットが 1 回の FD_READ 通知につき 1 つの RECV 呼び出しのみ許可するのに、CSocketFile と CSocket は FD_READ ごとに複数の RECV 呼び出しを許可するために起こる現象です。読み込むデータがない状態で FD_READ を取得した場合、アプリケーションはハングアップします。別の FD_READ を取得しない場合、アプリケーションはソケット上での通信を停止します。
この問題は次のように解決できます。ソケットから読み込まれるデータが TCP パケット 1 つのサイズを超える (ネットワーク メディアの最大伝送単位は通常 1,096 バイト以上) 場合は、メッセージ クラスの Serialize メソッドを呼び出す前に、ソケット クラスの OnReceive メソッドで、CAsyncSocket::IOCtl(FIONREAD, ...) を呼び出します。利用可能なデータが必要以下のサイズである場合は、すべてのデータを受け取るまで待機し、その後読み取り操作のみ開始します。
次の例の m_dwExpected は、ユーザーが受信すると予想されるバイト数の概数です。これをコード内のどこかで宣言していると仮定します。
void CChatSocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);
DWORD dwReceived;
if (IOCtl(FIONREAD, &dwReceived))
{
if (dwReceived >= m_dwExpected) // Process only if you have enough data
m_pDoc->ProcessPendingRead();
}
else
{
// Error handling here
}
}
詳細については、「MFC における Windows ソケット、「Windows ソケット : アーカイブ付きソケットの使用」と「Windows Sockets 2 API」を参照してください。
必要条件
ヘッダー : afxsock.h