Класс CSocketCSocket Class

Является производным от класса CAsyncSocket , наследует его инкапсуляцию API-интерфейса сокетов Windows и представляет более высокий уровень абстракции, чем CAsyncSocket объект.Derives from CAsyncSocket, inherits its encapsulation of the Windows Sockets API, and represents a higher level of abstraction than that of a CAsyncSocket object.

СинтаксисSyntax

class CSocket : public CAsyncSocket

ЧленыMembers

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

nameName ОписаниеDescription
CSocket:: CSocketCSocket::CSocket Формирует объект CSocket.Constructs a CSocket object.

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

nameName ОписаниеDescription
CSocket:: AttachCSocket::Attach Присоединяет к объекту маркер СОКЕТа CSocket .Attaches a SOCKET handle to a CSocket object.
CSocket:: КанцелблоккингкаллCSocket::CancelBlockingCall Отменяет выполняющийся в данный момент блокирующий вызов.Cancels a blocking call that is currently in progress.
CSocket:: CreateCSocket::Create Создает сокет.Creates a socket.
CSocket:: FromHandleCSocket::FromHandle Возвращает указатель на CSocket объект по заданному маркеру сокета.Returns a pointer to a CSocket object, given a SOCKET handle.
CSocket:: BlockCSocket::IsBlocking Определяет, выполняется ли блокирующий вызов.Determines whether a blocking call is in progress.

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

ИмяName ОписаниеDescription
CSocket:: ОнмессажепендингCSocket::OnMessagePending Вызывается для обработки ожидающих сообщений при ожидании завершения блокирующего вызова.Called to process pending messages while waiting for a blocking call to complete.

КомментарииRemarks

CSocket работает с классами CSocketFile и CArchive для управления отправкой и получением данных.CSocket works with classes CSocketFile and CArchive to manage the sending and receiving of data.

CSocketОбъект также предоставляет блокировку, которая необходима для синхронной работы CArchive .A CSocket object also provides blocking, which is essential to the synchronous operation of CArchive. Блокирующие функции, такие как Receive ,, Send ReceiveFrom , SendTo и Accept (все унаследованные от CAsyncSocket ), не возвращают WSAEWOULDBLOCK ошибку в CSocket .Blocking functions, such as Receive, Send, ReceiveFrom, SendTo, and Accept (all inherited from CAsyncSocket), do not return a WSAEWOULDBLOCK error in CSocket. Вместо этого эти функции ожидают завершения операции.Instead, these functions wait until the operation completes. Кроме того, исходный вызов будет завершаться ошибкой ВСАЕИНТР, если CancelBlockingCall вызывается, когда одна из этих функций блокируется.Additionally, the original call will terminate with the error WSAEINTR if CancelBlockingCall is called while one of these functions is blocking.

Чтобы использовать CSocket объект, вызовите конструктор, а затем вызовите, Create чтобы создать базовый маркер сокета (тип Socket).To use a CSocket object, call the constructor, then call Create to create the underlying SOCKET handle (type SOCKET). Параметры по умолчанию для Create создания сокета потока, но если сокет не используется с CArchive объектом, можно указать параметр для создания сокета датаграммы или выполнить привязку к определенному порту для создания сокета сервера.The default parameters of Create create a stream socket, but if you are not using the socket with a CArchive object, you can specify a parameter to create a datagram socket instead, or bind to a specific port to create a server socket. Подключитесь к сокету клиента с помощью Connect на стороне клиента и Accept на стороне сервера.Connect to a client socket using Connect on the client side and Accept on the server side. Затем создайте CSocketFile объект и свяжите его с CSocket объектом в CSocketFile конструкторе.Then create a CSocketFile object and associate it to the CSocket object in the CSocketFile constructor. Затем создайте CArchive объект для отправки данных, а другой — для получения (при необходимости), а затем свяжите их с CSocketFile объектом в CArchive конструкторе.Next, create a CArchive object for sending and one for receiving data (as needed), then associate them with the CSocketFile object in the CArchive constructor. После завершения обмена данными удалите CArchive CSocketFile объекты, и CSocket .When communications are complete, destroy the CArchive, CSocketFile, and CSocket objects. Тип данных СОКЕТа описан в статье Windows Sockets: Background.The SOCKET data type is described in the article Windows Sockets: Background.

При использовании CArchive с CSocketFile и CSocket может возникнуть ситуация, когда CSocket::Receive вводит цикл (by PumpMessages(FD_READ) ) в ожидании запрошенного объема байтов.When you use CArchive with CSocketFile and CSocket, you might encounter a situation where CSocket::Receive enters a loop (by PumpMessages(FD_READ)) waiting for the requested amount of bytes. Это обусловлено тем, что сокеты Windows допускают только один вызов recv per FD_READ уведомления, но CSocketFile и CSocket разрешают несколько вызовов recv per FD_READ.This is because Windows sockets allow only one recv call per FD_READ notification, but CSocketFile and CSocket allow multiple recv calls per FD_READ. Если при отсутствии данных для чтения появляется FD_READ, приложение зависает.If you get an FD_READ when there is no data to read, the application hangs. Если вы никогда не получаете другой FD_READ, приложение перестает взаимодействовать через сокет.If you never get another FD_READ, the application stops communicating over the socket.

Эту проблему можно устранить следующим образом.You can resolve this problem as follows. В OnReceive методе класса Socket вызовите CAsyncSocket::IOCtl(FIONREAD, ...) метод перед вызовом Serialize метода класса сообщений, когда ожидаемые данные, считываемые из сокета, превышают размер одного пакета TCP (максимальная единица передачи, обычно по крайней мере 1096 байт).In the OnReceive method of your socket class, call CAsyncSocket::IOCtl(FIONREAD, ...) before you call the Serialize method of your message class when the expected data to be read from the socket exceeds the size of one TCP packet (maximum transmission unit of the network medium, usually at least 1096 bytes). Если размер доступных данных меньше, чем требуется, дождитесь получения всех данных и запустите операцию чтения только после этого.If the size of the available data is less than needed, wait for all the data to be received and only then start the read operation.

В следующем примере m_dwExpected — это приблизительное число байтов, которое должен получить пользователь.In the following example, m_dwExpected is the approximate number of bytes that the user expects to receive. Предполагается, что вы объявили его в любом расположении в коде.It is assumed that you declare it elsewhere in your code.

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 в каждом потоке, использующем сокеты для инициализации библиотек сокетов.When using MFC sockets in secondary threads in a statically linked MFC application, you must call AfxSocketInit in each thread that uses sockets to initialize the socket libraries. По умолчанию AfxSocketInit метод вызывается только в основном потоке.By default, AfxSocketInit is called only in the primary thread.

Дополнительные сведения см. в статьях сокеты Windows в MFC, сокеты Windows: Использование сокетов с архивами, сокеты Windows: как работают сокеты с архивами, сокеты Windows: последовательность операций, сокеты Windows: пример сокетов с использованием архивов.For more information, see Windows Sockets in MFC, Windows Sockets: Using Sockets with Archives, Windows Sockets: How Sockets with Archives Work, Windows Sockets: Sequence of Operations, Windows Sockets: Example of Sockets Using Archives.

Иерархия наследованияInheritance Hierarchy

CObjectCObject

CAsyncSocketCAsyncSocket

CSocket

ТребованияRequirements

Заголовок: афкссокк. hHeader: afxsock.h

CSocket:: AttachCSocket::Attach

Вызовите эту функцию-член, чтобы присоединить hSocket маркер к CSocket объекту.Call this member function to attach the hSocket handle to a CSocket object.

BOOL Attach(SOCKET hSocket);

ПараметрыParameters

хсоккетhSocket
Содержит маркер для сокета.Contains a handle to a socket.

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

Ненулевое значение, если функция выполнена успешно.Nonzero if the function is successful.

КомментарииRemarks

Маркер СОКЕТа хранится в элементе данных m_hSocket объекта.The SOCKET handle is stored in the object's m_hSocket data member.

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

ПримерExample

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:: КанцелблоккингкаллCSocket::CancelBlockingCall

Вызовите эту функцию-член для отмены блокирующего вызова, выполняемого в данный момент.Call this member function to cancel a blocking call currently in progress.

void CancelBlockingCall();

КомментарииRemarks

Эта функция отменяет все невыполненные операции блокировки для этого сокета.This function cancels any outstanding blocking operation for this socket. Исходный вызов блокировки будет завершаться как можно скорее с ошибкой ВСАЕИНТР.The original blocking call will terminate as soon as possible with the error WSAEINTR.

В случае блокирующей Connect операции реализация сокетов Windows будет завершать блокирование как можно скорее, но ресурсы сокета могут быть освобождены до тех пор, пока подключение не будет завершено (а затем не будет сброшено) или истекло время ожидания. Это может быть заметным, только если приложение сразу же пытается открыть новый сокет (если нет доступных сокетов) или подключиться к тому же узлу.In the case of a blocking Connect operation, the Windows Sockets implementation will terminate the blocking call as soon as possible, but it may not be possible for the socket resources to be released until the connection has completed (and then been reset) or timed out. This is likely to be noticeable only if the application immediately tries to open a new socket (if no sockets are available), or to connect to the same peer.

Отмена любой операции, отличной от Accept , может привести к неопределенному состоянию сокета.Canceling any operation other than Accept can leave the socket in an indeterminate state. Если приложение отменяет операцию блокировки на сокете, то единственной операцией, которую приложение может зависеть от выполнения на сокете, является вызов Close , хотя другие операции могут работать с некоторыми реализациями сокетов Windows.If an application cancels a blocking operation on a socket, the only operation that the application can depend on being able to perform on the socket is a call to Close, although other operations may work on some Windows Sockets implementations. Если вы хотите обеспечить максимальную переносимость приложения, необходимо соблюдать осторожность, чтобы не зависеть от выполнения операций после отмены.If you desire maximum portability for your application, you must be careful not to depend on performing operations after a cancel.

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

CSocket:: CreateCSocket::Create

Вызовите функцию создания члена после создания объекта сокета, чтобы создать сокет Windows и присоединить его.Call the Create member function after constructing a socket object to create the Windows socket and attach it.

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

ПараметрыParameters

нсоккетпортnSocketPort
Определенный порт, используемый с сокетом, или значение 0, если необходимо выбрать порт в MFC.A particular port to be used with the socket, or 0 if you want MFC to select a port.

нсоккеттипеnSocketType
SOCK_STREAM или SOCK_DGRAM.SOCK_STREAM or SOCK_DGRAM.

лпсзсоккетаддрессlpszSocketAddress
Указатель на строку, содержащую сетевой адрес подключенного сокета, разделенный цифрой, например "128.56.22.8".A pointer to a string containing the network address of the connected socket, a dotted number such as "128.56.22.8". Передача строки NULL для этого параметра указывает на то, что CSocket экземпляр должен прослушивать активность клиента во всех сетевых интерфейсах.Passing the NULL string for this parameter indicates the CSocket instance should listen for client activity on all network interfaces.

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

Ненулевое значение, если функция выполнена успешно; в противном случае — 0, и конкретный код ошибки можно получить, вызвав GetLastError .Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling GetLastError.

КомментарииRemarks

Create затем вызывает метод Bind , чтобы привязать сокет к указанному адресу.Create then calls Bind to bind the socket to the specified address. Поддерживаются следующие типы сокетов:The following socket types are supported:

  • SOCK_STREAM предоставляет последовательные, надежные, двусторонние байтовые потоки, основанные на подключениях.SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. Использует протокол TCP для семейства Интернет-адресов.Uses Transmission Control Protocol (TCP) for the Internet address family.

  • SOCK_DGRAM поддерживает датаграммы без установления соединения, ненадежные буферы фиксированной (обычно небольшой) максимальной длины.SOCK_DGRAM Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Использует протокол UDP для семейства Интернет-адресов.Uses User Datagram Protocol (UDP) for the Internet address family. Чтобы использовать этот параметр, не следует использовать сокет с CArchive объектом.To use this option, you must not use the socket with a CArchive object.

    Примечание

    AcceptФункция-член принимает ссылку на новый пустой CSocket объект в качестве параметра.The Accept member function takes a reference to a new, empty CSocket object as its parameter. Этот объект необходимо создать перед вызовом метода Accept .You must construct this object before you call Accept. Помните, что если объект сокета выходит за пределы области действия, соединение закрывается.Keep in mind that if this socket object goes out of scope, the connection closes. Не вызывайте Create этот новый объект сокета.Do not call Create for this new socket object.

Дополнительные сведения о потоковых и многопортовых сокетах см. в статьях Windows Sockets: фоновый режим, сокеты Windows: порты и адреса сокетов, а также сокеты Windows. Использование сокетов с архивами.For more information about stream and datagram sockets, see the articles Windows Sockets: Background, Windows Sockets: Ports and Socket Addresses, and Windows Sockets: Using Sockets with Archives.

CSocket:: CSocketCSocket::CSocket

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

CSocket();

КомментарииRemarks

После создания необходимо вызвать Create функцию члена.After construction, you must call the Create member function.

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

CSocket:: FromHandleCSocket::FromHandle

Возвращает указатель на CSocket объект.Returns a pointer to a CSocket object.

static CSocket* PASCAL FromHandle(SOCKET hSocket);

ПараметрыParameters

хсоккетhSocket
Содержит маркер для сокета.Contains a handle to a socket.

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

Указатель на CSocket объект или значение null, если нет CSocket объекта, присоединенного к хсоккет.A pointer to a CSocket object, or NULL if there is no CSocket object attached to hSocket.

КомментарииRemarks

Если при задании маркера СОКЕТа CSocket объект не присоединен к этому обработчику, функция-член возвращает значение NULL и не создает временный объект.When given a SOCKET handle, if a CSocket object is not attached to the handle, the member function returns NULL and does not create a temporary object.

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

CSocket:: BlockCSocket::IsBlocking

Вызовите эту функцию-член, чтобы определить, выполняется ли блокирующий вызов.Call this member function to determine if a blocking call is in progress.

BOOL IsBlocking();

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

Ненулевое значение, если сокет блокируется; в противном случае — 0.Nonzero if the socket is blocking; otherwise 0.

КомментарииRemarks

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

CSocket:: ОнмессажепендингCSocket::OnMessagePending

Переопределите эту функцию члена, чтобы искать определенные сообщения в Windows и реагировать на них в сокете.Override this member function to look for particular messages from Windows and respond to them in your socket.

virtual BOOL OnMessagePending();

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

Ненулевое значение, если сообщение было обработано; в противном случае — 0.Nonzero if the message was handled; otherwise 0.

КомментарииRemarks

Это расширенный переопределяемый объект.This is an advanced overridable.

Платформа вызывается, OnMessagePending пока сокет переводит сообщения Windows, чтобы дать вам возможность работать с сообщениями, представляющими интерес для вашего приложения.The framework calls OnMessagePending while the socket is pumping Windows messages to give you an opportunity to deal with messages of interest to your application. Примеры использования см OnMessagePending . в статье сокеты Windows: наследование от классов сокетов.For examples of how you might use OnMessagePending, see the article Windows Sockets: Deriving from Socket Classes.

Дополнительные сведения см. в разделе сокеты Windows: Использование сокетов с архивами.For more information, see Windows Sockets: Using Sockets with Archives.

См. также разделSee also

Класс CAsyncSocketCAsyncSocket Class
Иерархическая диаграммаHierarchy Chart
Класс CAsyncSocketCAsyncSocket Class
Класс CSocketFileCSocketFile Class