分享方式:


CSocket 類別

衍生自 CAsyncSocket,繼承其 Windows Sockets 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至關重要。 封鎖函式,例如 ReceiveSendReceiveFromSendTo、 和 Accept (全部繼承自 CAsyncSocket),不會在 中CSocket傳回WSAEWOULDBLOCK錯誤。 相反地,這些函式會等到作業完成為止。 此外,如果在 CancelBlockingCall 其中一個函式封鎖時呼叫,原始呼叫將會終止並出現錯誤 WSAEINTR。

若要使用 CSocket 物件,請呼叫 建構函式,然後呼叫 Create 以建立基礎 SOCKET 句柄 (類型 SOCKET)。 建立數據流套接字的預設參數 Create ,但如果您未搭配 CArchive 物件使用套接字,您可以指定參數來建立數據報套接字,或系結至特定埠以建立伺服器套接字。 在客戶端和Accept伺服器端使用 Connect 連接到用戶端套接字。 然後建立 CSocketFile 物件,並將它與 CSocket 建構函式中的 CSocketFile 對象產生關聯。 接下來,建立對象來傳送,並建立一個 CArchive 接收數據的物件(視需要),然後將它們與 CSocketFile 建構函式中的 CArchive 對象產生關聯。 通訊完成時,終結 CArchiveCSocketFileCSocket 物件。 數據類型SOCKET會在 Windows Sockets:Background 一文中說明。

當您搭配 和 使用 CArchive 時,可能會遇到進入迴圈(byPumpMessages(FD_READ))等候要求位元組量的情況CSocket::ReceiveCSocketCSocketFile 這是因為 Windows 套接字每個通知只允許一個 recv 呼叫 FD_READ ,但 CSocketFile 允許 CSocket 每個 FD_READ進行多個 recv 呼叫。 如果您在沒有要讀取數據時收到 FD_READ ,則應用程式會停止回應。 如果您從未取得另一個 FD_READ,應用程式會停止透過套接字進行通訊。

您可以依照下列方式解決此問題。 在套接字類別的 方法中 OnReceiveCAsyncSocket::IOCtl(FIONREAD, ...) 當您從套接字讀取預期的數據超過一個 TCP 封包的大小時,請先呼叫 Serialize 訊息類別的方法(網路媒體的最大傳輸單位,通常是至少 1096 個字節)。 如果可用數據的大小小於需求,請等候接收所有數據,然後才開始讀取作業。

在下列範例中, 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 應用程式中的次要線程中使用 MFC 套接字時,您必須在每個使用套接字來初始化套接字連結庫的線程中呼叫 AfxSocketInit 。 根據預設, AfxSocketInit 只會在主要線程中呼叫 。

如需詳細資訊,請參閱 MFC 中的 Windows 套接字、Windows 套接字:使用套接字搭配封存、Windows 套接字:使用封存的套接字的方式Windows 套接字:作業順序、Windows 套接字:使用封存的套接字範例。

繼承階層架構

CObject

CAsyncSocket

CSocket

需求

標頭: afxsock.h

CSocket::Attach

呼叫這個成員函式,將句柄附加 hSocketCSocket 物件。

BOOL Attach(SOCKET hSocket);

參數

hSocket
包含套接字的句柄。

傳回值

如果函式成功,則為非零。

備註

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 Sockets 實作會儘快終止封鎖呼叫,但在連線完成或逾時之前,可能無法釋放套接字資源。只有當應用程式立即嘗試開啟新的套接字(如果沒有套接字可用),或聯機到相同的對等時,這才可能很明顯。

取消以外的 Accept 任何作業可能會使套接字處於不確定狀態。 如果應用程式取消套接字上的封鎖作業,則應用程式唯一可以依賴在套接字上執行的作業是呼叫 Close,不過其他作業可能在某些 Windows Sockets 實作上運作。 如果您想要應用程式的最大可移植性,您必須小心不要依賴在取消之後執行作業。

如需詳細資訊,請參閱 Windows 套接字:搭配封存使用套接字。

CSocket::Create

Create在建構套接字對象之後呼叫成員函式,以建立 Windows 套接字並附加它。

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

參數

nSocketPort
要與套接字搭配使用的特定埠,如果您想要 MFC 選取埠,則為 0。

nSocketType
SOCK_STREAMSOCK_DGRAM

lpszSocketAddress
字串的指標,包含已連線套接字的網路位址,即點數,例如 “128.56.22.8”。 傳遞此參數的NULL字串表示 CSocket 實例應該接聽所有網路介面上的客戶端活動。

傳回值

如果函式成功,則為非零;否則,您可以呼叫 GetLastError來擷取 0,並擷取特定的錯誤碼。

備註

Create 然後呼叫 Bind ,將套接字系結至指定的位址。 支援下列套接字型態:

  • SOCK_STREAM 提供循序、可靠、雙向、以連線為基礎的位元組數據流。 針對因特網位址系列使用傳輸控制通訊協定 (TCP)。

  • SOCK_DGRAM 支持數據報,這些數據報是無連接、不可靠的固定緩衝區(通常很小)最大長度。 針對因特網位址系列使用用戶數據報通訊協定 (UDP)。 若要使用此選項,您不得將套接字與 物件搭配 CArchive 使用。

    注意

    成員 Accept 函式會採用對新的空白 CSocket 物件做為其參數的參考。 您必須先建構這個物件,才能呼叫 Accept。 請記住,如果這個套接字物件超出範圍,連線就會關閉。 請勿呼叫 Create 這個新的套接字物件。

如需數據流和數據報套接字的詳細資訊,請參閱 Windows 套接字:背景、Windows 套接字:埠和套接字位址,以及 Windows 套接字:搭配封存使用套接字一文。

CSocket::CSocket

建構 CSocket 物件。

CSocket();

備註

建構之後,您必須呼叫 Create 成員函式。

如需詳細資訊,請參閱 Windows 套接字:搭配封存使用套接字。

CSocket::FromHandle

傳回 物件的指標 CSocket

static CSocket* PASCAL FromHandle(SOCKET hSocket);

參數

hSocket
包含套接字的句柄。

傳回值

物件的指標CSocket,如果沒有附加至 hSocket的物件,NULLCSocket為 。

備註

當指定 SOCKET 句柄時,如果 CSocket 物件未附加至句柄,成員函式會 NULL 傳回且不會建立暫存物件。

如需詳細資訊,請參閱 Windows 套接字:搭配封存使用套接字。

CSocket::IsBlocking

呼叫這個成員函式,以判斷封鎖呼叫是否正在進行中。

BOOL IsBlocking();

傳回值

如果套接字封鎖,則為非零;否則為 0。

備註

如需詳細資訊,請參閱 Windows 套接字:搭配封存使用套接字。

CSocket::OnMessagePending

覆寫此成員函式以尋找來自 Windows 的特定訊息,並在套接字中回應它們。

virtual BOOL OnMessagePending();

傳回值

如果已處理訊息,則為非零;否則為 0。

備註

這是可覆寫的進階。

當套接字正在提取 Windows 訊息時,架構會呼叫 OnMessagePending ,讓您有機會處理應用程式感興趣的訊息。 如需如何使用 OnMessagePending的範例,請參閱 Windows 套接字:衍生自套接字類別一文

如需詳細資訊,請參閱 Windows 套接字:搭配封存使用套接字。

另請參閱

CAsyncSocket
階層架構圖表
CAsyncSocket
CSocketFile