Windows 套接字:操作顺序

本文并列说明了服务器套接字和客户端套接字的操作顺序。 由于套接字使用 CArchive 对象,因此它们一定是流套接字

流套接字通信的操作顺序

在构造 CSocketFile 对象之前,以下顺序对于 CAsyncSocketCSocket 都是准确的(有一些参数差异)。 从这一刻起,该顺序严格适用于 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
  1. 其中 nPort 是端口号。 有关端口的详细信息,请参阅 Windows 套接字:端口和套接字地址

  2. 服务器必须始终指定端口,这样客户端才能连接。 Create 调用有时还指定地址。 在客户端上,使用默认参数,这要求 MFC 使用任何可用端口。

  3. 其中 nPort 是端口号,strAddr 是计算机地址或 Internet 协议 (IP) 地址。

  4. 计算机地址可以采用几种形式:“ftp.microsoft.com”、“microsoft.com”。 IP 地址使用“以点分隔的数字”形式:“127.54.67.32”。 Connect 函数检查地址是否为以点分隔的数字(尽管它不会检查以确保该数字是网络上的有效计算机)。 如果不是,Connect 会假定一个其他形式的计算机名称。

  5. 在服务器端调用 Accept 时,你要传递对新套接字对象的引用。 必须首先构造此对象,但不要为其调用 Create。 请记住,如果此套接字对象超出范围,则会关闭连接。 MFC 将新对象连接到 SOCKET 句柄。 可以在堆栈上构造套接字(如上所示),或者在堆上构建。

  6. 存档和套接字文件会在套接字超出范围时关闭。 当对象超出范围或被删除时,套接字对象的析构函数也会调用套接字对象的 Close 成员函数。

有关顺序的其他说明

上表中所示的调用顺序适用于流套接字。 数据报套接字(无连接)不需要 CAsyncSocket::ConnectListenAccept 调用(尽管可以选择使用 Connect)。 相反,如果使用类 CAsyncSocket,则数据报套接字使用 CAsyncSocket::SendToReceiveFrom 成员函数。 (如果将 Connect 用于数据报套接字,则使用 SendReceive。)由于 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