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
、 、 SendTo
ReceiveFrom
Send
Accept
、、(すべて継承CAsyncSocket
元) などのReceive
ブロッキング関数は、エラーをWSAEWOULDBLOCK
CSocket
返しません。 代わりに、これらの関数は操作が完了するまで待機します。 さらに、これらの関数のいずれかがブロックされている間に呼び出された場合 CancelBlockingCall
、元の呼び出しはエラー WSAEINTR で終了します。
オブジェクトをCSocket
使用するには、コンストラクターを呼び出してから、基になるSOCKET
ハンドル (型) を作成する呼び出Create
しを行いますSOCKET
。 ストリーム ソケットの作成の既定の Create
パラメーターですが、オブジェクトで CArchive
ソケットを使用していない場合は、代わりにデータグラム ソケットを作成するパラメーターを指定するか、特定のポートにバインドしてサーバー ソケットを作成できます。 クライアント側とAccept
サーバー側を使用してConnect
、クライアント ソケットに接続します。 次に、オブジェクトを CSocketFile
作成し、コンストラクター内の CSocket
オブジェクトに CSocketFile
関連付けます。 次に、送信用の CArchive
オブジェクトとデータを受信するためのオブジェクト (必要に応じて) を作成し、それらをコンストラクター内の CSocketFile
オブジェクトに CArchive
関連付けます。 通信が完了したら、オブジェクト、およびオブジェクトCSocketFile
をCArchive
CSocket
破棄します。 データ型についてはSOCKET
、Windows ソケット: 背景に関する記事を参照してください。
と共にCSocketFile
CSocket
使用CArchive
すると、要求されたバイト数を待機するループ (byPumpMessages(FD_READ)
) に入る状況CSocket::Receive
が発生する可能性があります。 これは、Windows ソケットでは通知ごとに 1 つの recv 呼び出ししか許可されませんがCSocketFile
、1 回あたりFD_READ
FD_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 ソケット: アーカイブを使用するソケットの例」を参照してください。
継承階層
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
オブジェクトがアタッチされていないCSocket
hSocket
場合。
解説
ハンドルが SOCKET
指定されると、オブジェクトがハンドルにアタッチされていない場合 CSocket
、メンバー関数は一時オブジェクトを NULL
返し、作成しません。
詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。
CSocket::IsBlocking
このメンバー関数を呼び出して、ブロック呼び出しが進行中かどうかを判断します。
BOOL IsBlocking();
戻り値
ソケットがブロックしている場合は 0 以外。それ以外の場合は 0。
解説
詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。
CSocket::OnMessagePending
このメンバー関数をオーバーライドして、Windows から特定のメッセージを検索し、ソケットでそれらに応答します。
virtual BOOL OnMessagePending();
戻り値
メッセージが処理された場合は 0 以外。それ以外の場合は 0。
解説
これは、高度なオーバーライドが可能です。
このフレームワークは、ソケットが Windows メッセージをポンプしている間に呼び出 OnMessagePending
し、アプリケーションに関心のあるメッセージを処理する機会を提供します。 使用方法OnMessagePending
の例については、Windows ソケット: ソケット クラスからの派生に関する記事を参照してください。
詳細については、「Windows ソケット: アーカイブでのソケットの使用」を参照してください。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示