Windows Sockets:背景知识

本文介绍 Windows Sockets 的性质和用途。其他内容还包括:


  • 定义术语“套接字”。
  • 描述 SOCKET 句柄数据类型。
  • 描述套接字的用途。

 

Windows Sockets 规范为 Microsoft Windows
定义了一个二进制兼容网络编程接口。Windows Sockets 基于 Berkeley Software Distribution(BSD,4.3 版)中的
UNIX 套接字实现,后者是美国加州大学伯克利分校开发的。该规范包括针对 Windows 的 BSD 样式套接字例程和扩展。通过使用 Windows
Sockets,应用程序能够在任何符合 Windows Sockets API 的网络上通信。在 Win32 上,Windows Sockets 提供线程安全。

许多网络软件供应商支持网络协议下的 Windows Sockets,这些协议包括:传输控制协议/网际协议
(TCP/IP)、Xerox 网络系统 (XNS)、Digital Equipment Corporation 的 DECNet 协议和
Novell Corporation 的互联网包交换协议/顺序分组报文交换协议 (IPX/SPX) 等。虽然目前的 Windows Sockets 规范定义了
TCP/IP 的套接字抽象化,但任何网络协议都可以通过提供自己版本的、实现 Windows Sockets 的动态链接库 (DLL) 来满足 Windows
Sockets。用 Windows Sockets 编写的商用应用程序示例包括 X Windows 服务器、终端模拟器和电子邮件系统。

注意: Windows Sockets
的用途是将基础网络抽象出来,这样,您不必对网络非常了解,并且您的应用程序可在任何支持套接字的网络上运行。因此,本文档不讨论网络协议的细节内容。

 

Microsoft 基础类库 (MFC) 通过提供两个类来支持使用 Windows Sockets
API 进行编程。其中一个类为 CSocket ,它提供高级抽象化来简化网络通信编程。

Windows Sockets 规范“Windows Sockets:用于 Microsoft
Windows 环境下的网络计算的开放接口”现在为 1.1 版本,它是 TCP/IP
群体中一个由个人和公司组成的大团体开发的,是一个开放的网络标准,可免费使用。套接字编程模型当前支持一个“通信域”,该“通信域”使用网际协议组 (Internet
Protocol Suite)。该规范可在 Platform SDK 中获得。


提示: 因为套接字使用网际协议组,所以它们对于支持“信息高速公路”上 Internet 通信的应用程序是首选方式。

套接字的定义


 

套接字是一个通信终结点,它是 Windows Sockets
应用程序用来在网络上发送或接收数据包的对象。套接字具有类型,与正在运行的进程相关联,并且可以有名称。目前,套接字一般只与使用网际协议组的同一“通信域”中的其他套接字交换数据。

这两种套接字都是双向的,是可以同时在两个方向上(全双工)进行通信的数据流。

可用的套接字类型有以下两种:


  • 流式套接字

     

    流式套接字提供没有记录边界的数据流,即字节流。字节流能确保以正确的顺序无重复地被送达。

  • 数据文报套接字

     

    数据文报套接字支持面向记录的数据流,但不能确保能被送达,也无法确保按照发送顺序或不重复。


 

“有序”指数据包按发送的顺序送达。“不重复”指一个特定的数据包只能获取一次。

注意: 在某些网络协议下(如 XNS),流可以面向记录,即作为记录流而非字节流。但在更常用的 TCP/IP
协议下,流为字节流。Windows Sockets 提供与基础协议无关的抽象化级别。

 

有关上述类型以及各种套接字适用情形的信息,请参见 Windows Sockets:流式套接字Windows Sockets:数据文报套接字

SOCKET 数据类型

每一个 MFC 套接字对象封装一个 Windows Sockets 对象的句柄。该句柄的数据类型为
SOCKET。SOCKET 句柄类似于窗口的 HWND。MFC 套接字类提供对封装句柄的操作。

Platform SDK 中详细描述了 SOCKET 数据类型。

套接字的用途

套接字的作用非常大,至少在下面三种通信上下文中如此:


  • 客户端/服务器模型。
  • 对等网络方案,如聊天应用程序。
  • 通过让接收应用程序将消息解释为函数调用来进行远程过程调用 (RPC)。

提示: 最适合使用 MFC 套接字的情况是当同时编写通信的两端时:在两端都使用 MFC。有关该主题(包括如何管理与非
MFC 应用程序通信的情况)的更多信息,请参见 Windows Sockets:字节排序


Windows Sockets:流式套接字

http://tech.163.com/school · 2005-10-09 15:03:48 ·
来源: MSDN


 

本文描述流式套接字,它是两种可用的 Windows Sockets 类型中的一种。(另一种类型是数据文报套接字 。)

流式套接字提供没有记录边界的数据流:可以是双向的字节流(应用程序是全双工:可以通过套接字同时传输和接收)。可依赖流传递有序的、不重复的数据。(“有序”指数据包按发送顺序送达。“不重复”指一个特定的数据包只能获取一次。)这能确保收到流消息,而流非常适合处理大量数据。

网络传输层可将数据拆分为或分组为若干个大小适当的数据包。 CSocket
类将为您处理打包和解包。

流基于显式连接:套接字 A 请求与套接字 B 建立连接;套接字 B 接受或拒绝此连接请求。

打电话的情况与流非常相似:正常情况下,接听方听到您的话和您讲话时的顺序一样,没有重复和遗漏。流套接字适合文件传输协议
(FTP) 这类实现,此协议有利于传输任意大小的 ASCII 或二进制文件。

如果必须保证数据送达而且数据大小很大时,流式套接字优于数据文报套接字。有关流式套接字的更多信息,请参见
Windows Sockets 规范。该规范可在 Platform SDK 中获得。

MFC 示例 CHATTER CHATSRVR
都使用流式套接字。这些示例可能已经设计为使用数据文报套接字向网络上的所有接收套接字广播。而目前的设计更好,这是因为:


  • 广播模型受制于网络“洪水”(或“风暴”)问题。
  • 后来采用的客户端-服务器模型更有效。
  • 流式模型提供可靠的数据传输,数据文报模型则未提供。
  • 最终模型利用在 CArchive 类借给 CSocket 类的 Unicode 和 ANSI 套接字应用程序之间通信的能力。

注意: 如果使用 CSocket 类,则必须使用流。如果将套接字类型指定为 SOCK_DGRAM ,则 MFC
断言失败。


Windows Sockets:数据文报套接字

http://tech.163.com/school · 2005-10-09 15:15:43
· 来源: MSDN


 

本文描述数据文报套接字,它是两种可用的 Windows Sockets 类型中的一种。(另一种类型是
流式套接字 。)

数据文报套接字支持双向数据流,此数据留不能保证按顺序和不重复送达。数据文报也不保证是可靠的;它们可能无法到达目的地。数据文报可能不按顺序到达并且可能会重复,但只要记录的大小没有超过接收端的内部大小限制,就会保持数据中的记录边界。您负责管理顺序和可靠性。(可靠性在局域网
[LAN] 上往往很好,但在广域网 [WAN] 如 Internet 上却不太好。)

数据文报为“无连接”的,也就是不建立显式连接。可将数据文报消息发送到指定的套接字,然后从指定的套接字接收消息。

数据文报套接字的一个示例是使网络上的系统时钟保持同步的应用程序。这阐释了数据文报套接字的一个附加功能,即至少在某些设置中,向大量的网络地址广播消息。

在面向记录的数据方面,数据文报套接字优于流式套接字。有关数据文报套接字的更多信息,请参见
Platform SDK 中的 Windows Sockets 规范。


Windows Sockets:字节排序

http://tech.163.com/school · 2005-10-09 16:30:27 ·
来源: MSDN


 

本文以及另外两篇相关文章解释 Windows Sockets 编程方面的一些问题。本文介绍字节排序。其他问题在文章 Windows Sockets:阻塞Windows Sockets:转换字符串中介绍。

如果使用 CAsyncSocket 类或从其派生,则您需要自己管理这些问题。如果您使用 CSocket 类或从其派生,则由 MFC

管理它们。

字节排序


不同的计算机结构有时使用不同的字节顺序存储数据。例如,基于 Intel 的计算机存储数据的顺序与 Macintosh

(Motorola) 计算机相反。Intel 字节顺序称为“Little-Endian”,与网络标准“Big-Endian”顺序也相反。下表解

释这些术语。

Big-Endian 和 Little-Endian 字节排序

字节排序 含义
Big-Endian 最重要的字节在词的左端。
Little-Endian 最重要的字节在词的右端。

通常,您不必为在网络上发送和接收的数据的字节顺序转换担心,但在有些情况下,您必须转换字节顺序。

何时必须转换字节顺序


在下列情况中需要转换字节顺序:


  • 传递的信息需要由网络解释(与发送到另一台计算机的数据相反)。例如,可能传递端口和地址,这些信息

必须为网络理解。


  • 与之通信的服务器应用程序不是 MFC 应用程序(并且没有它的源代码)。如果两台计算机不共享相同的字节

排序,则需要字节顺序转换。

何时不必转换字节顺序


在下列情况下可以免去转换字节顺序的工作:


  • 两端的计算机可以同意不交换字节,并且这两台计算机使用相同的字节顺序。
  • 与之通信的服务器是 MFC 应用程序。
  • 有与之通信的服务器的源代码,因此可以明确地判断是否必须转换字节顺序。
  • 可以将服务器移植到 MFC。这样做相当容易,所得到的通常是更小、更快的代码。

使用 CAsyncSocket 时,您必须自己管理任何必需的字节顺序转换。Windows Sockets 将“Big-Endian”字节顺

序模型标准化,并提供在该顺序和其他顺序之间转换的函数。然而,与 CSocket 一起使用的 CArchive 使用相

反的顺序(“Little-Endian”),但 CArchive 为您管理字节顺序转换的细节。通过在应用程序中使用这种标准

排序,或通过使用 Windows Sockets 字节顺序转换函数,可增强代码的可移植性。

最适合使用 MFC 套接字的情况是当编写通信的两端时:在两端都使用 MFC。如果正在编写将与非 MFC 应用程序

通信的应用程序(如 FTP 服务器),则在向存档对象传递数据前,您可能需要使用 Windows Sockets 转换例程

ntohs ntohl htons htonl
自己管理字节交换。本文稍后将给出这些用于与非 MFC 应用程序通信的函数

示例。


注意 当通信的另一端不是 MFC 应用程序时,也必须避免将从 CObject 派生的 C++ 对象以流的形式输入存

档,因为接收端无法处理它们。请参见 Windows
Sockets:使用带存档的套接字
中的说明。


有关字节顺序的更多信息,请参见 Platform SDK 中的 Windows Sockets 规范。

字节顺序转换示例


下面的示例显示使用存档的 CSocket 对象的一个序列化函数。它还阐释了在 Windows Sockets API 中如何使用

字节顺序转换函数。

该示例显示这样的情形:您正在编写与非 MFC 服务器应用程序通信的客户程序,而您没有访问该服务器应用程序

源代码的权限。在这种情况下,必须假设非 MFC 服务器使用标准的网络字节顺序。相反,MFC 客户端应用程序对

CSocket 对象使用 CArchive 对象,而 CArchive
使用与网络标准相反的“Little-Endian”字节顺序。

假设要与之通信的非 MFC 服务器具有如下已建立的消息包协议:

struct Message { long MagicNumber; unsigned short Command; short Param1; long Param2; }; 

上述内容用 MFC 术语表示则为:

struct Message { long m_lMagicNumber; short m_nCommand; short m_nParam1; long m_lParam2; void Serialize 

( CArchive& ar ); };

在 C++ 中, struct 和类在本质上是一回事。 Message
结构可以有成员函数,如以上声明的 Serialize
成员函数。

Serialize 成员函数可能为如下形式: void Message::Serialize(CArchive& ar)
{
if (ar.IsStoring())

{
ar < < (DWORD)htonl(m_lMagicNumber);
ar < <
(WORD)htons(m_nCommand);
ar < < (WORD)htons(m_nParam1);
ar <
< (DWORD)htonl(m_lParam2);
}
else
{
WORD w;
DWORD dw;

ar > > dw;
m_lMagicNumber = ntohl((long)dw);
ar > > w ;

m_nCommand = ntohs((short)w);
ar > > w;
m_nParam1 =
ntohs((short)w);
ar > > dw;
m_lParam2 = ntohl((long)dw);
}

}

该示例要求进行数据字节顺序转换,因为一端的非 MFC 服务器应用程序的字节排序与另一端在 MFC 客户端应用程序中使用的 CArchive
明显不匹配。该示例阐释了 Windows Sockets 提供的几个字节顺序转换函数。下表描述了这些函数。

Windows Sockets 字节顺序转换函数

函数 作用
ntohs 将 16 位数量从网络字节顺序转换为主机字节顺序(从 Big-Endian 转换为 Little-Endian)。
ntohl 将 32 位数量从网络字节顺序转换为主机字节顺序(从 Big-Endian 转换为 Little-Endian)。
htons 将 16 位数量从主机字节顺序转换为网络字节顺序(从 Little-Endian 转换为 Big-Endian)。
htonl 将 32 位数量从主机字节顺序转换为网络字节顺序(从 Little-Endian 转换为 Big-Endian)。

此示例的另一个要点是,当通信另一端的套接字应用程序为非 MFC 应用程序时,必须避免出现如下列语句的操作:

ar pMsg; 

这里的 pMsg 是指向从 CObject 类派生的 C++
对象的指针。这将发送多余的与对象关联的 MFC 信息,而服务器并不理解这些信息,因为只有服务器是 MFC 应用程序时才理解。

有关更多信息,请参见:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值