CSocketFile Class
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at CSocketFile Class.
A CFile
object used for sending and receiving data across a network via Windows Sockets.
Syntax
class CSocketFile : public CFile
Members
Public Constructors
Name | Description |
---|---|
CSocketFile::CSocketFile | Constructs a CSocketFile object. |
Remarks
You can attach the CSocketFile
object to a CSocket
object for this purpose. You also can, and usually do, attach the CSocketFile
object to a CArchive
object to simplify sending and receiving data using MFC serialization.
To serialize (send) data, you insert it into the archive, which calls CSocketFile
member functions to write data to the CSocket
object. To deserialize (receive) data, you extract from the archive. This causes the archive to call CSocketFile
member functions to read data from the CSocket
object.
Tip
Besides using CSocketFile
as described here, you can use it as a stand-alone file object, just as you can with CFile
, its base class. You can also use CSocketFile
with any archive-based MFC serialization functions. Because CSocketFile
does not support all of CFile
's functionality, some default MFC serialize functions are not compatible with CSocketFile
. This is particularly true of the CEditView
class. You should not try to serialize CEditView
data through a CArchive
object attached to a CSocketFile
object using CEditView::SerializeRaw
; use CEditView::Serialize instead. The SerializeRaw
function expects the file object to have functions, such as Seek
, that CSocketFile
does not have.
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. 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. If you get an FD_READ when there is no data to read, the application hangs. If you never get another FD_READ, the application stops communicating over the socket.
You can resolve this problem as follows. 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.
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
}
}
For more information, see Windows Sockets in MFC, Windows Sockets: Using Sockets with Archives, as well as Windows Sockets 2 API.
Inheritance Hierarchy
CSocketFile
Requirements
Header: afxsock.h
CSocketFile::CSocketFile
Constructs a CSocketFile
object.
explicit CSocketFile(
CSocket* pSocket,
BOOL bArchiveCompatible = TRUE);
Parameters
pSocket
The socket to attach to the CSocketFile
object.
bArchiveCompatible
Specifies whether the file object is for use with a CArchive
object. Pass FALSE only if you want to use the CSocketFile
object in a stand-alone manner as you would a stand-alone CFile
object, with certain limitations. This flag changes how the CArchive
object attached to the CSocketFile
object manages its buffer for reading.
Remarks
The object's destructor disassociates itself from the socket object when the object goes out of scope or is deleted.
Note
A CSocketFile
can also be used as a (limited) file without a CArchive
object. By default, the CSocketFile
constructor's bArchiveCompatible
parameter is TRUE. This specifies that the file object is for use with an archive. To use the file object without an archive, pass FALSE in the bArchiveCompatible
parameter.
In its "archive compatible" mode, a CSocketFile
object provides better performance and reduces the danger of a "deadlock." A deadlock occurs when both the sending and receiving sockets are waiting on each other, or for a common resource. This situation might occur if the CArchive
object worked with the CSocketFile
the way it does with a CFile
object. With CFile
, the archive can assume that if it receives fewer bytes than it requested, the end of file has been reached.
With CSocketFile
, however, data is message based; the buffer can contain multiple messages, so receiving fewer than the number of bytes requested does not imply end of file. The application does not block in this case as it might with CFile
, and it can continue reading messages from the buffer until the buffer is empty. The CArchive::IsBufferEmpty function is useful for monitoring the state of the archive's buffer in such a case.
For more information on the use of CSocketFile
, see the articles Windows Sockets: Using Sockets with Archives and Windows Sockets: Example of Sockets Using Archives.
See Also
CFile Class
Hierarchy Chart
CAsyncSocket Class
CSocket Class