Класс CSocket
Производный от CAsyncSocket
, наследует его инкапсуляцию API сокетов Windows и представляет более высокий уровень абстракции, чем 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
и (все наследуемыеCAsyncSocket
), не возвращают ошибкуWSAEWOULDBLOCK
.CSocket
Accept
ReceiveFrom
Send
Receive
Вместо этого эти функции ожидают завершения операции. Кроме того, исходный вызов завершится ошибкой WSAEINTR, если CancelBlockingCall
вызывается во время блокировки одной из этих функций.
Чтобы использовать CSocket
объект, вызовите конструктор, а затем вызовите Create
базовый SOCKET
дескриптор (тип SOCKET
). Параметры Create
по умолчанию для создания сокета потока, но если вы не используете сокет с CArchive
объектом, можно указать параметр для создания сокета диаграммы данных или привязать к конкретному порту для создания сокета сервера. Подключитесь к сокету клиента, используя Connect
на стороне клиента и Accept
на стороне сервера. Затем создайте CSocketFile
объект и свяжите его с CSocket
объектом в конструкторе CSocketFile
. Затем создайте CArchive
объект для отправки и одного для получения данных (по мере необходимости), а затем свяжите их с CSocketFile
объектом в конструкторе CArchive
. После завершения обмена данными уничтожайте CArchive
CSocketFile
объекты и CSocket
объекты. Тип SOCKET
данных описан в статье Сокеты Windows: Фон.
При использовании CArchive
и CSocketFile
CSocket
может возникнуть ситуация, когда 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: пример сокетов с помощью архивов.
Иерархия наследования
CSocket
Требования
Заголовок: afxsock.h
CSocket::Attach
Вызовите эту функцию-член, чтобы подключить дескриптор к объекту hSocket
CSocket
.
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
Класс