共用方式為


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 時,可能會遇到進入迴圈(by PumpMessages(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