Поделиться через


Класс CSocket

Производный от CAsyncSocket, наследует его инкапсуляцию API сокетов Windows и представляет более высокий уровень абстракции, чем CAsyncSocket объект.

Синтаксис

class CSocket : public CAsyncSocket

Участники

Открытые конструкторы

Имя Описание
CSocket::CSocket Формирует объект CSocket.

Открытые методы

Имя Описание
CSocket::Attach Присоединяет дескриптор к объекту SOCKETCSocket .
CSocket::CancelBlockingCall Отменяет блокирующий вызов, который в настоящее время выполняется.
CSocket::Create Создает сокет.
CSocket::FromHandle Возвращает указатель на CSocket объект, заданный дескриптором SOCKET .
CSocket::IsBlocking Определяет, выполняется ли блокирующий вызов.

Защищенные методы

Имя Описание
CSocket::OnMessagePending Вызывается для обработки ожидающих сообщений во время ожидания завершения блокирующего вызова.

Замечания

CSocket работает с классами CSocketFile и CArchive управляет отправкой и получением данных.

Объект CSocket также обеспечивает блокировку, которая является важной для синхронной операции CArchive. Блокирующие функции, такие как , , SendToи (все наследуемыеCAsyncSocket), не возвращают ошибкуWSAEWOULDBLOCK.CSocketAcceptReceiveFromSendReceive Вместо этого эти функции ожидают завершения операции. Кроме того, исходный вызов завершится ошибкой WSAEINTR, если CancelBlockingCall вызывается во время блокировки одной из этих функций.

Чтобы использовать CSocket объект, вызовите конструктор, а затем вызовите Create базовый SOCKET дескриптор (тип SOCKET). Параметры Create по умолчанию для создания сокета потока, но если вы не используете сокет с CArchive объектом, можно указать параметр для создания сокета диаграммы данных или привязать к конкретному порту для создания сокета сервера. Подключение к сокету клиента, используемому Connect на стороне клиента и Accept на стороне сервера. Затем создайте CSocketFile объект и свяжите его с CSocket объектом в конструкторе CSocketFile . Затем создайте CArchive объект для отправки и одного для получения данных (по мере необходимости), а затем свяжите их с CSocketFile объектом в конструкторе CArchive . После завершения обмена данными уничтожайте CArchiveCSocketFileобъекты и CSocket объекты. Тип SOCKET данных описан в статье Сокеты Windows: Фон.

При использовании CArchive и CSocketFileCSocketможет возникнуть ситуация, когда CSocket::Receive введите цикл (по PumpMessages(FD_READ)) ожидая запрошенного количества байтов. Это связано с тем, что сокеты Windows разрешают только один вызов recv для каждого FD_READ уведомления, но CSocketFile и CSocket разрешают несколько вызовов recv для каждого FD_READ. Если данные отсутствуют FD_READ для чтения, приложение зависает. Если вы никогда не получаете другого FD_READ, приложение перестает взаимодействовать по сокету.

Эту проблему можно устранить следующим образом. В методе OnReceive класса сокета вызовите перед вызовом CAsyncSocket::IOCtl(FIONREAD, ...)Serialize метода класса сообщений, когда ожидаемые данные из сокета превышают размер одного TCP-пакета (максимальная единица передачи сетевого носителя, обычно не менее 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 вызывается только в основном потоке.

Дополнительные сведения см. в разделе "Сокеты Windows" в MFC, сокетах 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 завершит вызов блокировки как можно скорее, но может быть невозможно освободить ресурсы сокета до завершения подключения (а затем сброса) или истечения времени ожидания. Это может быть заметно только в том случае, если приложение немедленно пытается открыть новый сокет (если сокеты недоступны) или подключиться к одному одноранговому узлу.

Отмена любой операции, отличной от Accept возможности выхода сокета в неопределенном состоянии. Если приложение отменяет блокировку в сокете, единственная операция, которую приложение может зависеть от возможности выполнения сокета, является вызовом Close, хотя другие операции могут работать в некоторых реализациях сокетов Windows. Если требуется максимальная переносимость для приложения, следует будьте осторожны, чтобы не зависеть от выполнения операций после отмены.

Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами".

CSocket::Create

Create Вызовите функцию-член после создания объекта сокета, чтобы создать сокет Windows и подключить его.

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

Параметры

nSocketPort
Конкретный порт, используемый с сокетом или 0, если требуется выбрать порт MFC.

nSocketType
SOCK_STREAM или SOCK_DGRAM.

lpszSocketAddress
Указатель на строку, содержащую сетевой адрес подключенного сокета, точечного числа, например "128.56.22.8". Передача строки NULL для этого параметра указывает, CSocket что экземпляр должен прослушивать действия клиента во всех сетевых интерфейсах.

Возвращаемое значение

Ненулевое значение, если функция выполнена успешно; в противном случае 0 и определенный код ошибки можно получить путем вызова GetLastError.

Замечания

Create затем вызывает Bind привязку сокета к указанному адресу. Поддерживаются следующие типы сокетов:

  • SOCK_STREAM Предоставляет последовательность, надежные, двусторонние потоки на основе подключения. Использует протокол управления передачей (TCP) для семейства адресов Интернета.

  • SOCK_DGRAM Поддерживает диаграммы данных, которые являются ненадежными, ненадежными буферами фиксированной (обычно небольшой) максимальной длины. Использует протокол пользовательской диаграммы данных (UDP) для семейства адресов Интернета. Чтобы использовать этот параметр, не следует использовать сокет с CArchive объектом.

    Примечание.

    Функция-член Accept принимает ссылку на новый пустой CSocket объект в качестве параметра. Перед вызовом Acceptнеобходимо создать этот объект. Помните, что если этот объект сокета выходит из область, соединение закрывается. Не вызывайте Create этот новый объект сокета.

Дополнительные сведения о сокетах потоков и диаграмм данных см. в статьях "Сокеты Windows: фон, сокеты Windows: порты и сокеты Windows, а также сокеты Windows: использование сокетов с архивами.

CSocket::CSocket

Формирует объект CSocket.

CSocket();

Замечания

После строительства необходимо вызвать функцию-член Create .

Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами".

CSocket::FromHandle

Возвращает указатель на CSocket объект.

static CSocket* PASCAL FromHandle(SOCKET hSocket);

Параметры

hSocket
Содержит дескриптор сокета.

Возвращаемое значение

Указатель на CSocket объект или NULL объект, к которому не CSocket подключен hSocketобъект.

Замечания

При указании дескриптора, если CSocket объект не присоединен к дескрипторуSOCKET, функция-член возвращается NULL и не создает временный объект.

Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами".

CSocket::IsBlocking

Вызовите эту функцию-член, чтобы определить, выполняется ли блокирующий вызов.

BOOL IsBlocking();

Возвращаемое значение

Ненулевое значение, если сокет блокируется; в противном случае — 0.

Замечания

Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами".

CSocket::OnMessagePending

Переопределите эту функцию-член, чтобы искать определенные сообщения из Windows и отвечать на них в сокете.

virtual BOOL OnMessagePending();

Возвращаемое значение

Ненулевое значение, если сообщение было обработано; в противном случае — 0.

Замечания

Это расширенная переопределение.

Платформа вызывает OnMessagePending , пока сокет выкачивает сообщения Windows, чтобы предоставить вам возможность иметь дело с сообщениями, интересующими ваше приложение. Примеры использования OnMessagePendingсм. в статье Сокеты Windows: производные от классов сокетов.

Дополнительные сведения см. в статье "Сокеты Windows: использование сокетов с архивами".

См. также

CAsyncSocket Класса
Диаграмма иерархии
CAsyncSocket Класса
CSocketFile Класса