Compartir a través de


CSocketFile (clase)

Se utiliza un objeto CFile para enviar y recibir datos a través de una red mediante Windows Sockets.

Sintaxis

class CSocketFile : public CFile

Miembros

Constructores públicos

Nombre Descripción
CSocketFile::CSocketFile Construye un objeto CSocketFile.

Comentarios

Puede adjuntar el objeto CSocketFile a un objeto CSocket para este fin. También puede adjuntar, y normalmente lo hará, el objeto CSocketFile a un objeto CArchive para simplificar el envío y la recepción de datos mediante la serialización de MFC.

Para serializar (enviar) datos, insértelos en el archivo, que llama a CSocketFile funciones miembro para escribir datos en el objeto CSocket. Para deserializar (recibir) datos, extraiga del archivo. Esto hace que el archivo llame a CSocketFile funciones miembro para leer datos del objeto CSocket.

Sugerencia

Además de usar CSocketFile como se describe aquí, puede usarlo como un objeto de archivo independiente, igual que puede con CFile, su clase base. También puede usar CSocketFile con cualquier función de serialización MFC basada en archivo. Dado que CSocketFile no admite toda la funcionalidad de CFile, algunas funciones de serialización de MFC predeterminadas no son compatibles con CSocketFile. Esto es especialmente cierto en la clase CEditView. No se debe intentar serializar los datos CEditView a través de un objeto CArchive adjunto a un objeto CSocketFile mediante CEditView::SerializeRaw; use CEditView::Serialize en su lugar. La función SerializeRaw espera que el objeto de archivo tenga las funciones, como Seek, que CSocketFile no posee.

Cuando se usa CArchive con CSocketFile y CSocket, podría encontrarse con una situación en la que CSocket::Receive entra en un bucle (por PumpMessages(FD_READ)) esperando la cantidad solicitada de bytes. Esto se debe a que los sockets de Windows solo permiten una llamada de recepción por notificación FD_READ, pero CSocketFile y CSocket permiten varias llamadas de recepción por FD_READ. Si recibe una llamada FD_READ cuando no hay datos que leer, la aplicación se bloquea. Si nunca recibe otra llamada FD_READ, la aplicación deja de comunicarse a través del socket.

Puede resolver este problema como se indica a continuación. En el método OnReceive de la clase de socket, llame a CAsyncSocket::IOCtl(FIONREAD, ...) antes de llamar al método Serialize de la clase de mensaje cuando los datos que esperan a ser leídos del socket superen el tamaño de un paquete TCP (unidad de transmisión máxima del medio de red, normalmente al menos 1096 bytes). Si el tamaño de los datos disponibles es menor que el necesario, espere a que se reciban todos los datos y solo inicie la operación de lectura.

En el ejemplo siguiente, m_dwExpected es el número aproximado de bytes que el usuario espera recibir. Se supone que se declara en otra parte del código.

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
   }
}

Para obtener más información, vea Windows Sockets en MFC, Windows Sockets: Uso de sockets con archivos, así como la API de Windows Sockets 2.

Jerarquía de herencia

CObject

CFile

CSocketFile

Requisitos

Encabezado: afxsock.h

CSocketFile::CSocketFile

Construye un objeto CSocketFile.

explicit CSocketFile(
    CSocket* pSocket,
    BOOL bArchiveCompatible = TRUE);

Parámetros

pSocket
Socket que se va a adjuntar al objeto CSocketFile.

bArchiveCompatible
Especifica si el objeto de archivo se usa con un objeto CArchive. Pase FALSE solo si desea usar el objeto CSocketFile de forma independiente como lo haría con un objeto independiente CFile, con ciertas limitaciones. Esta marca cambia la forma en que el objeto CArchive adjunto al objeto CSocketFile administra su búfer para su lectura.

Comentarios

El destructor del objeto se desasocia del objeto socket cuando el objeto sale del ámbito o se elimina.

Nota:

También se puede usar CSocketFile como un archivo (limitado) sin un objeto CArchive. De forma predeterminada, el parámetro bArchiveCompatible del constructor CSocketFile es TRUE. Esto especifica que el objeto de archivo es para su uso con un archivo. Para usar el objeto de archivo sin un archivo, pase FALSE en el parámetro bArchiveCompatible.

En su modo "compatible con el archivo", un objeto CSocketFile proporciona un mejor rendimiento y reduce el peligro de un "interbloqueo". Un interbloqueo se produce cuando los sockets de envío y recepción se están esperando entre sí o un recurso común. Esta situación podría producirse si el objeto CArchive funcionaba con la forma CSocketFile en que lo hace con un objeto CFile. Con CFile, el archivo puede suponer que si recibe menos bytes de los solicitados, se ha alcanzado el final del archivo.

Sin embargo, con CSocketFile, los datos se basan en mensajes; el búfer puede contener varios mensajes, por lo que recibir menos del número de bytes solicitados no implica el final del archivo. La aplicación no se bloquea en este caso, ya que puede con CFile, y puede continuar leyendo mensajes desde el búfer hasta que el búfer esté vacío. La función CArchive::IsBufferEmpty es útil para supervisar el estado del búfer del archivo en tal caso.

Para obtener más información sobre el uso de CSocketFile, vea los artículos Windows Sockets: Uso de sockets con archivos y Windows Sockets: Ejemplo de sockets que usan archivos.

Consulte también

CFile (clase)
Gráfico de jerarquías
CAsyncSocket (clase)
CSocket (clase)