Windows 套接字:操作顺序
本文并列说明了服务器套接字和客户端套接字的操作顺序。 由于套接字使用 CArchive
对象,因此它们一定是流套接字。
流套接字通信的操作顺序
在构造 CSocketFile
对象之前,以下顺序对于 CAsyncSocket
和 CSocket
都是准确的(有一些参数差异)。 从这一刻起,该顺序严格适用于 CSocket
。 下表说明了在客户端和服务器之间建立通信的操作顺序。
设置服务器与客户端之间的通信
服务器 | 客户端 |
---|---|
// construct a socket CSocket sockSrvr; |
// construct a socket CSocket sockClient; |
// create the SOCKET sockSrvr.Create(nPort); 1,2 |
// create the SOCKET sockClient.Create( ); 2 |
// start listening sockSrvr.Listen( ); |
|
// seek a connection sockClient.Connect(strAddr, nPort); 3,4 |
|
// construct a new, empty socket CSocket sockRecv; // accept connection sockSrvr.Accept( sockRecv ); 5 |
|
// construct file object CSocketFile file(&sockRecv); |
// construct file object CSocketFile file(&sockClient); |
// construct an archive CArchive arIn(&file, CArchive::load); - 或者 - CArchive arOut(&file, CArchive::store); - 或两者 - |
// construct an archive CArchive arIn(&file, CArchive::load); - 或者 - CArchive arOut(&file, CArchive::store); - 或两者 - |
// use the archive to pass data: arIn >> dwValue; - 或者 - arOut << dwValue; 6 |
// use the archive to pass data: arIn >> dwValue; - 或者 - arOut << dwValue; 6 |
其中 nPort 是端口号。 有关端口的详细信息,请参阅 Windows 套接字:端口和套接字地址。
服务器必须始终指定端口,这样客户端才能连接。
Create
调用有时还指定地址。 在客户端上,使用默认参数,这要求 MFC 使用任何可用端口。其中 nPort 是端口号,strAddr 是计算机地址或 Internet 协议 (IP) 地址。
计算机地址可以采用几种形式:“ftp.microsoft.com”、“microsoft.com”。 IP 地址使用“以点分隔的数字”形式:“127.54.67.32”。
Connect
函数检查地址是否为以点分隔的数字(尽管它不会检查以确保该数字是网络上的有效计算机)。 如果不是,Connect
会假定一个其他形式的计算机名称。在服务器端调用
Accept
时,你要传递对新套接字对象的引用。 必须首先构造此对象,但不要为其调用Create
。 请记住,如果此套接字对象超出范围,则会关闭连接。 MFC 将新对象连接到 SOCKET 句柄。 可以在堆栈上构造套接字(如上所示),或者在堆上构建。存档和套接字文件会在套接字超出范围时关闭。 当对象超出范围或被删除时,套接字对象的析构函数也会调用套接字对象的 Close 成员函数。
有关顺序的其他说明
上表中所示的调用顺序适用于流套接字。 数据报套接字(无连接)不需要 CAsyncSocket::Connect、Listen 和 Accept 调用(尽管可以选择使用 Connect
)。 相反,如果使用类 CAsyncSocket
,则数据报套接字使用 CAsyncSocket::SendTo
和 ReceiveFrom
成员函数。 (如果将 Connect
用于数据报套接字,则使用 Send
和 Receive
。)由于 CArchive
不适用于数据报,因此,如果套接字是数据报,请不要将 CSocket
与存档一起使用。
CSocketFile 并不能支持所有 CFile
功能;对于套接字通信而言没有意义的 CFile
成员(例如 Seek
)不可用。 因此,一些默认的 MFC Serialize
函数与 CSocketFile
不兼容。 这对 CEditView
类尤其如此。 不应尝试使用 CEditView::SerializeRaw
通过附加到 CSocketFile
对象的 CArchive
对象来序列化 CEditView
数据;改而使用 CEditView::Serialize
(未记录在文档中)。 SerializeRaw 函数希望文件对象具有 CSocketFile
不支持的函数,例如 Seek
。
有关详细信息,请参阅:
另请参阅
MFC 中的 Windows 套接字
CSocket 类
CAsyncSocket::Create
CAsyncSocket::Close