CSocket クラス

CAsyncSocketから派生し、Windows ソケット API のカプセル化を継承し、オブジェクトの抽象化よりも高いレベルの抽象化をCAsyncSocket表します。

構文

class CSocket : public CAsyncSocket

メンバー

パブリック コンストラクター

名前 説明
CSocket::CSocket CSocket オブジェクトを構築します。

パブリック メソッド

名前 説明
CSocket::Attach オブジェクトに SOCKET ハンドルを CSocket アタッチします。
CSocket::CancelBlockingCall 現在進行中のブロック呼び出しを取り消します。
CSocket::Create ソケットを作成します。
CSocket::FromHandle ハンドルを指定して、オブジェクトへの CSocket ポインターを SOCKET 返します。
CSocket::IsBlocking ブロック呼び出しが進行中かどうかを判断します。

保護メソッド

名前 説明
CSocket::OnMessagePending ブロック呼び出しの完了を待機している間に保留中のメッセージを処理するために呼び出されます。

解説

CSocket はクラス CSocketFile と連携し、 CArchive データの送受信を管理します。

CSocketオブジェクトはブロックも提供します。これはCArchive、 、 SendToReceiveFromSendAccept 、、(すべて継承CAsyncSocket元) などのReceiveブロッキング関数は、エラーをWSAEWOULDBLOCKCSocket返しません。 代わりに、これらの関数は操作が完了するまで待機します。 さらに、これらの関数のいずれかがブロックされている間に呼び出された場合 CancelBlockingCall 、元の呼び出しはエラー WSAEINTR で終了します。

オブジェクトをCSocket使用するには、コンストラクターを呼び出してから、基になるSOCKETハンドル (型) を作成する呼び出Createしを行いますSOCKET。 ストリーム ソケットの作成の既定の Create パラメーターですが、オブジェクトで CArchive ソケットを使用していない場合は、代わりにデータグラム ソケットを作成するパラメーターを指定するか、特定のポートにバインドしてサーバー ソケットを作成できます。 クライアント側とAcceptサーバー側を使用してConnect、クライアント ソケットに接続します。 次に、オブジェクトを CSocketFile 作成し、コンストラクター内の CSocket オブジェクトに CSocketFile 関連付けます。 次に、送信用の CArchive オブジェクトとデータを受信するためのオブジェクト (必要に応じて) を作成し、それらをコンストラクター内の CSocketFile オブジェクトに CArchive 関連付けます。 通信が完了したら、オブジェクト、およびオブジェクトCSocketFileCArchiveCSocket破棄します。 データ型についてはSOCKET、Windows ソケット: 背景に関する記事を参照してください。

と共にCSocketFileCSocket使用CArchiveすると、要求されたバイト数を待機するループ (byPumpMessages(FD_READ)) に入る状況CSocket::Receiveが発生する可能性があります。 これは、Windows ソケットでは通知ごとに 1 つの recv 呼び出ししか許可されませんがCSocketFile、1 回あたりFD_READFD_READ複数の recv 呼び出しCSocketが許可されるためです。 読み取る FD_READ データがない場合は、アプリケーションがハングします。 別 FD_READのアプリケーションを取得しない場合、アプリケーションはソケット経由で通信を停止します。

この問題は、次のように解決できます。 OnReceiveソケット クラスのメソッドで、ソケットから読み取られる予想されるデータが 1 つの TCP パケットのサイズ (ネットワーク メディアの最大送信単位、通常は少なくとも 1096 バイト) を超えたときに、メッセージ クラスのメソッドを呼び出す前に呼び出CAsyncSocket::IOCtl(FIONREAD, ...)Serializeします。 使用可能なデータのサイズが必要未満の場合は、すべてのデータが受信されるのを待ってから、読み取り操作を開始します。

次の例では、 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
   }
}

Note

静的にリンクされた MFC アプリケーションのセカンダリ スレッドで MFC ソケットを使用する場合は、ソケットを使用してソケット ライブラリを初期化する各スレッドで呼び出す AfxSocketInit 必要があります。 既定では、 AfxSocketInit プライマリ スレッドでのみ呼び出されます。

詳細については、「 MFC の Windows ソケット、 Windows ソケット: アーカイブでのソケットの使用、 Windows ソケット: アーカイブを使用したソケットの動作Windows ソケット: 操作のシーケンス、 Windows ソケット: アーカイブを使用するソケットの例」を参照してください。

継承階層

CObject

CAsyncSocket

CSocket

必要条件

ヘッダー:afxsock.h

CSocket::Attach

このメンバー関数を呼び出して、ハンドルを hSocket オブジェクトに CSocket アタッチします。

BOOL Attach(SOCKET hSocket);

パラメーター

hSocket
ソケットへのハンドルを格納します。

戻り値

正常終了した場合は 0 以外を返します。

解説

ハンドルは SOCKET オブジェクト m_hSocket のデータ メンバーに格納されます。

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

class CSockThread : public CWinThread
{
public:
   SOCKET m_hConnected;

protected:
   CChatSocket m_sConnected;

   // remainder of class declaration omitted.

 

BOOL CSockThread::InitInstance()
{
   // Attach the socket object to the socket handle
   // in the context of this thread.
   m_sConnected.Attach(m_hConnected);
   m_hConnected = NULL;

   return TRUE;
}

 

// This listening socket has been constructed
// in the primary thread.
void CListeningSocket::OnAccept(int nErrorCode)
{
   UNREFERENCED_PARAMETER(nErrorCode);

   // This CSocket object is used just temporarily
   // to accept the incoming connection.
   CSocket sConnected;
   Accept(sConnected);

   // Start the other thread.
   CSockThread *pSockThread = (CSockThread*)AfxBeginThread(
       RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
   if (NULL != pSockThread)
   {
      // Detach the newly accepted socket and save
      // the SOCKET handle in our new thread object.
      // After detaching it, it should no longer be
      // used in the context of this thread.
      pSockThread->m_hConnected = sConnected.Detach();
      pSockThread->ResumeThread();
   }
}

CSocket::CancelBlockingCall

現在進行中のブロック呼び出しを取り消すには、このメンバー関数を呼び出します。

void CancelBlockingCall();

解説

この関数は、このソケットの未処理のブロック操作を取り消します。 元のブロッキング呼び出しは、エラー WSAEINTRでできるだけ早く終了します。

ブロック Connect 操作の場合、Windows ソケットの実装はできるだけ早くブロック呼び出しを終了しますが、接続が完了 (リセットされた後) またはタイムアウトになるまでソケット リソースを解放できない場合があります。これは、アプリケーションがすぐに新しいソケットを開こうとした場合 (使用可能なソケットがない場合)、または同じピアに接続しようとした場合にのみ顕著になる可能性があります。

ソケットを不確定な状態のままにできる以外 Accept の操作を取り消す。 アプリケーションがソケットでブロック操作を取り消した場合、アプリケーションがソケットで実行できることに依存できる唯一の操作は呼び出し Closeですが、他の操作は一部の Windows ソケットの実装で動作する可能性があります。 アプリケーションの移植性を最大限に高める必要がある場合は、キャンセル後の操作の実行に依存しないように注意する必要があります。

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

CSocket::Create

ソケット オブジェクトを Create 構築した後でメンバー関数を呼び出して、Windows ソケットを作成してアタッチします。

BOOL Create(
    UINT nSocketPort = 0,
    int nSocketType = SOCK_STREAM,
    LPCTSTR lpszSocketAddress = NULL);

パラメーター

nSocketPort
ソケットで使用する特定のポート。MFC でポートを選択する場合は 0。

nSocketType
SOCK_STREAM または SOCK_DGRAM

lpszSocketAddress
接続されているソケットのネットワーク アドレスを含む文字列へのポインター。"128.56.22.8" などのドット番号。 このパラメーターに NULL 文字列を渡すと、 CSocket インスタンスはすべてのネットワーク インターフェイスでクライアント アクティビティをリッスンする必要があることを示します。

戻り値

関数が成功した場合は 0 以外。それ以外の場合は 0 で、特定のエラー コードは呼び出 GetLastErrorすことによって取得できます。

解説

Create 次に、指定したアドレスにソケットをバインドする呼び出 Bind しを行います。 次のソケットの種類がサポートされています。

  • SOCK_STREAM シーケンス化された信頼性の高い双方向の接続ベースのバイト ストリームを提供します。 インターネット アドレス ファミリに伝送制御プロトコル (TCP) を使用します。

  • SOCK_DGRAM 固定 (通常は小さい) 最大長のコネクションレスで信頼性の低いバッファーであるデータグラムをサポートします。 インターネット アドレス ファミリにユーザー データグラム プロトコル (UDP) を使用します。 このオプションを使用するには、オブジェクトで CArchive ソケットを使用しないでください。

    Note

    Accept メンバー関数は、新しい空の CSocket オブジェクトへの参照をパラメーターとして受け取ります。 Accept を呼び出す前に、このオブジェクトを構築する必要があります。 このソケット オブジェクトがスコープ外になると、接続が閉じられることに注意してください。 この新しいソケット オブジェクトに対して Create を呼び出さないでください。

ストリーム ソケットとデータグラム ソケットの詳細については、「Windows ソケット: 背景」、Windows ソケット: ポートとソケット アドレスおよび Windows ソケット: アーカイブでのソケットの使用に関する記事を参照してください。

CSocket::CSocket

CSocket オブジェクトを構築します。

CSocket();

解説

構築後、メンバー関数を呼び出す Create 必要があります。

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

CSocket::FromHandle

CSocket オブジェクトへのポインターを返します。

static CSocket* PASCAL FromHandle(SOCKET hSocket);

パラメーター

hSocket
ソケットへのハンドルを格納します。

戻り値

オブジェクトへのCSocketポインター、またはNULLオブジェクトがアタッチされていないCSockethSocket場合。

解説

ハンドルが SOCKET 指定されると、オブジェクトがハンドルにアタッチされていない場合 CSocket 、メンバー関数は一時オブジェクトを NULL 返し、作成しません。

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

CSocket::IsBlocking

このメンバー関数を呼び出して、ブロック呼び出しが進行中かどうかを判断します。

BOOL IsBlocking();

戻り値

ソケットがブロックしている場合は 0 以外。それ以外の場合は 0。

解説

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

CSocket::OnMessagePending

このメンバー関数をオーバーライドして、Windows から特定のメッセージを検索し、ソケットでそれらに応答します。

virtual BOOL OnMessagePending();

戻り値

メッセージが処理された場合は 0 以外。それ以外の場合は 0。

解説

これは、高度なオーバーライドが可能です。

このフレームワークは、ソケットが Windows メッセージをポンプしている間に呼び出 OnMessagePending し、アプリケーションに関心のあるメッセージを処理する機会を提供します。 使用方法OnMessagePendingの例については、Windows ソケット: ソケット クラスからの派生に関する記事を参照してください。

詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。

関連項目

CAsyncSocket クラス
階層図
CAsyncSocket クラス
CSocketFile クラス