Windows Sockets 规范及应用

               

Windows Sockets 规范及应用

           -Windows网络编程接口

 


施 炜    李 铮    秦 颍         编著

 

******************************************************************
版权信息

    本书作者保留所有版权。禁止任何商业性的转载或复制。非赢利性质的转载和复制不得修改文章内容,并请保留此段文字。

Copyright (c) 1995-1996  By  施炜,李铮,秦颖
All Right Reserved
******************************************************************

 

 

 

内容提要

    本书适应了Windows、Internet及计算机网络普及的潮流,介绍了一套在Windows下网络编程的规范-Windows Sockets。这套规范是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。为使读者能够充分理解和应用这套规范,本书不但对Windows Sockets 1.1及2.0规范作了较为详尽的介绍,还结合了作者的实际工作,给出了具有实际应用价值的程序实例。书中的内容包括:Windows Sockets规范1.1版及2.0.8版介绍;Windows Sockets网络编程指导和具体应用实例;Windows Sockets规范1.1版及2.0.8版库函数参考等。
    本书体系完整,文字流畅,可供从事网络应用开发的工程技术人员和大专院校师生参考。

 


作者声明

    由于成书时间紧迫。本书不免有许多错误和不当之处,故此作者衷心希望各位读者能对本书提出宝贵意见(包括补充新的应用实例和内容),以便我们进一步修改完善此书。我们会尊重相应修订者的版权。作者也衷心希望在我们和各位读者的努力下,本书能够成为一本关于Windows Sockets编程的系统而又准确的免费中文参考书,为广大读者在Windows下网络编程提供帮助。

    作者联系地址:
    施炜:上海交通大学94032班   (200030)
          Email: weishi@fudan.ihep.ac.cn
    李铮:上海交通大学自动化系  (200030)
          Email: blee.bbs@captain.net.tsinghua.edu.cn
    秦颖:上海交通大学94033A班  (200030)
          Email: fluke.bbs@captain.net.tsinghua.edu.cn

    作者希望每一位拿到本书的读者能以任何方式通知我们。以便我们掌握本书的应用情况。并敬请各位读者暂时不要在其他FTP站点散发,谢谢合作。

编著者
1996年5月20日

前言

    当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。网络化是计算机技术九十年代的重要发展趋势之一。目前计算机网络的新发展是:异机种网络和异网互联有较大突破。TCP/IP协议在异网互联中体现出了其强大的生命力,以它为基础组建的Internet是目前国际上规模最大的计算机网间网,到1991年底世界上已有26个国家的五千多个网络连入Internet,其中包含了数千个组织的30万台主机,用户数以百万计。
    与计算机网络的普及相呼应的是Windows的广泛应用,现在在全世界各地已有超过四千万用户在使用不同版本的Windows。自1995年8月24日Windows 95正式推出以来,在短短的一个星期内销售量已超过100万份,有的零售商店不得不半夜开门,以迎接滚滚而来的抢购者。这说明以用户友好的图形界面为基础的Windows已得到用户的普遍认可,已经并将继续成为个人机平台上的事实上的操作系统标准。所以研究和开发在Windows下的网络编程技术具有普遍的应用价值。
    在Windows下的各种网络编程接口中,Windows Sockets脱颖而出,越来越得到大家的重视,这是因为Windows Sockets规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。
    在作者利用Windows Sockets规范进行应用开发的过程中,发现这方面的资料很少,特别是缺乏一本全面而实用的专著。为了使广大用户能够充分理解和应用这套规范,我们编写了这本书。本书不但对Windows Sockets 1.1及2.0规范作了较为详尽的介绍,还结合了作者的实际工作,给出了具有实际应用价值的程序实例。希望它能对Windows Sockets规范在国内的推广和应用起到抛砖引玉的作用。读者在阅读本书的过程中,如果能对自己的学习工作有所帮助和指导,是作者的最大愿望。由于时间紧迫,作者学识有限,书中错误在所难免,偏颇和不当之处,恳请读者不吝赐教。
    本书由施炜、李铮、秦颖合作完成,其中,第一、二、四、六章和5.2节由施炜编写;第七章、5.1节、3.4节由李铮编写;第5.3节、3.1-3.3节由秦颖编写。在本书的编写过程中,得到了上海交通大学的毛向辉先生的大力支持,并提供了一些最新的资料,在此谨表示衷心的谢意。

                                               编著者
                                        1995年9月于上海交通大学

目录
第一章 简介
1.1 什么是WINDOWS SOCKETS规范?
1.2 BEKELEY套接口
1.3 MICROSOFT WINDOWS和针对WINDOWS的扩展
1.4 这份规范的地位
1.5 曾经作过的修改
1.5.1 Windows Sockets 1.0
1.5.2 Windows Sockets 1.1
第二章 使用WINDOWS SOCKETS 1.1编程
2.1 WINDOWS SOCKETS协议栈安装检查
2.2 套接口
2.2.1 基本概念
2.2.2 客户机/服务器模型
2.2.3 带外数据
2.2.4 广播
2.3 字节顺序
2.4 套接口属性选项
2.5 数据库文件
2.6 与BERKELEY套接口的不同
2.6.1 套接口数据类型和错误数值
2.6.2 select()函数和FD_*宏
2.6.3 错误代码-errno,h_errno,WSAGetLastError()
2.6.4 指针
2.6.5 重命名的函数
2.6.5.1 close()和closesocket()
2.6.5.2 ioctl()和iooctlsocket()
2.6.6 阻塞例程和EINPROGRESS宏
2.6.7 Windows Sockets支持的最大套接口数目
2.6.8 头文件
2.6.9 API调用失败时的返回值
2.6.10 原始套接口
2.7 在多线程WINDOWS版本中的WINDOWS SOCKETS
第三章 WINDOWS SOCKETS 1.1应用实例
3.1 套接口网络编程原理
3.2 WINDOWS SOCKETS编程原理
3.3 WINDOWS SOCKETS与UNIX套接口编程实例
3.3.1 SERVER介绍
3.3.2 CLIENT介绍
3.3.3 源程序清单
3.4 另一个精巧的应用程序实例-WSHOUT
3.4.1 源程序目录
3.4.2 程序逻辑结构
3.4.3 源程序清单及注释
3.4.3.1 wshout.c清单
3.4.3.2 wshout.h清单
3.4.3.3 wshout.rc清单
3.4.3.4 ushout.c清单
3.4.3.5 ulisten.c清单
3.4.3.6 tshout.c清单
3.4.3.7 tlisten.c清单
3.4.3.8 errno.c清单
3.4.3.9 resolve.c清单
第四章 WINDOWS SOCKET 1.1库函数概览
4.1 套接口函数
4.1.1 阻塞/非阻塞和数据易失性
4.2 数据库函数
4.3 针对MICROSOFT WINDOWS的扩展函数
4.3.1 异步选择机制
4.3.2 异步支持例程
4.3.3 阻塞钩子函数方法
4.3.4 错误处理
4.3.5 通过中介DLL调用Windows Sockets DLL
4.3.6 Windows Sockets实现内部对消息的使用
4.3.7 私有的API接口
第五章 套接口库函数参考
5.1 WINDOWS SOCKET 1.1库函数参考
5.1.1 accept()
5.1.2 bind()
5.1.3 closesocket()
5.1.4 connect()
5.1.5 getpeername()
5.1.6 getsockname()
5.1.7 getsockopt()
5.1.8 htonl()
5.1.9 htons()
5.1.10 inet_addr()
5.1.11 inet_ntoa()
5.1.12 ioctlsocket()
5.1.13 listen()
5.1.14 ntohl()
5.1.15 ntohs()
5.1.16 recv()
5.1.17 recvfrom()
5.1.18 select()
5.1.19 send()
5.1.20 sendto()
5.1.21 setsockopt()
5.1.22 shutdown()
5.1.23 socket()
5.2 数据库函数
5.2.1 gethostbyaddr()
5.2.2 gethostbyname()
5.2.3 gethostname()
5.2.4 getprotobyname()
5.2.5 getprotobynumber()
5.2.6 getservbyname()
5.2.7 getservbyport()
5.3 WINDOWS扩展函数
5.3.1 WSAAsyncGetHostByAddr()
5.3.2 WSAAsyncGetHostByName()
5.3.3 WSAAsyncGetProtoByName()
5.3.4 WSAAsyncGetProtoByNumber()
5.3.5 WSAAsyncGetServByName()
5.3.6 WSAAsyncGetServByPort()
5.3.7 WSAAsyncSelect()
5.3.8 WSACancelAsyncRequest()
5.3.9 WSACancelBlockingCall()
5.3.10 WSACleanup()
5.3.11 WSAGetLastError()
5.3.12 WSAIsBlocking()
5.3.13 WSASetBlockingHook()
5.3.14 WSASetLastError()
5.3.15 WSAStartup()
5.3.16 WSAUnhookBlockingHook()
第六章 WINDOWS SOCKET 2的扩展特性
6.1 同时使用多个传输协议
6.2 与WINDOWS SOCKET 1.1应用程序的向后兼容性
6.2.1 源码的兼容性
6.2.2 二进制兼容性
6.3 在WINDOWS SOCKETS中注册传输协议
6.3.1 使用多个协议
6.3.2 select()函数应用中关于多个服务提供者的限制
6.4 协议无关的名字解析
6.5 重叠I/O和事件对象
6.5.1 事件对象
6.5.2 接收操作完成指示
6.5.2.1 阻塞并且等待完成指示。
6.5.2.2 检查完成指示
6.5.2.3 使用套接口I/O操作完成例程
6.5.3 WSAOVERLAPPED的细节
6.6 使用事件对象异步通知
6.7 服务的质量(QOS)
6.8 套接口组
6.9 共享套接口
6.10 连接建立和拆除的高级函数
6.11 扩展的字节顺序转换例程
6.12 分散/聚集方式I/O
6.13 协议无关的多点通讯
6.14 新增套接口选项一览
6.15 新增套接口IOCTL操作代码
6.16 新增函数一览
第七章 WINDOWS SOCKETS 2扩展库函数简要参考
7.1 WSAACCEPT()
7.2 WSACLOSEEVENT()
7.3 WSACONNECT()
7.4 WSACREATEEVENT()
7.5 WSADUPLICATESOCKET()
7.6 WSAENUMNETWORKEVENTS()
7.7 WSAENUMPROTOCOLS()
7.8 WSAEVENTSELECT()
7.9 WSAGETOVERLAPPEDRESULT()
7.10 WSAGETQOSBYNAME()
7.11 WSAHTONL()
7.12 WSAHTONS()
7.13 WSAIOCTL()
7.14 WSAJOINLEAF()
7.15 WSANTOHL()
7.16 WSANTOHS()
7.17 WSARECV()
7.18 WSARECVDISCONNECT()
7.19 WSARECVFROM()
7.20 WSARESETEVENT()
7.21 WSASEND()
7.22 WSASENDDISCONNECT()
7.23 WSASENDTO()
7.24 WSASETEVENT()
7.25 WSASOCKET()
7.26 WSAWAITFORMULTIPLEEVENTS()
附录A 错误代码
附录B WINDOWS SOCKETS头文件
附录B.1 WINDOWS SOCKETS 1.1头文件
附录B.2 WINDOWS SOCKETS 2头文件
附录B.3 WINSOCK.DEF文件
附录C 参考文献


第一章 简介
1.1 什么是Windows Sockets规范?
 Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套Micosoft Windows下网络编程接口。它不仅包含了人们所熟悉的Berkeley Socket风格的库函数;也包含了一组针对Windows的扩展库函数,以使程序员能充分地利用Windows消息驱动机制进行编程。
 Windows Sockets规范本意在于提供给应用程序开发者一套简单的API,并让各家网络软件供应商共同遵守。此外,在一个特定版本Windows的基础上,Windows Sockets也定义了一个二进制接口(ABI),以此来保证应用Windows Sockets API的应用程序能够在任何网络软件供应商的符合Windows Sockets协议的实现上工作。因此这份规范定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。
 遵守这套Windows Sockets规范的网络软件,我们称之为Windows Sockets兼容的,而Windows Sockets兼容实现的提供者,我们称之为Windows Sockets提供者。一个网络软件供应商必须百分之百地实现Windows Sockets规范才能做到现Windows Sockets兼容。
 任何能够与Windows Sockets兼容实现协同工作的应用程序就被认为是具有Windows Sockets接口。我们称这种应用程序为Windows Sockets应用程序。
 Windows Sockets规范定义并记录了如何使用API与Internet协议族(IPS,通常我们指的是TCP/IP)连接,尤其要指出的是所有的Windows Sockets实现都支持流套接口和数据报套接口.
    应用程序调用Windows Sockets的API实现相互之间的通讯。Windows Sockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如图1-1。

 虽然我们并不反对使用这一套API来实现另一通讯协议栈(而且我们期望在将来规范的修改中能够讨论这个问题),但这种用法已经超出了我们这一份规范所规定的范围,我们在此将不作讨论。


1.2 Bekeley套接口
 Windows Sockets规范是建立在Bekeley套接口模型上的。这个模型现在已是TCP/IP网络的标准。它提供了习惯于UNIX套接口编程的程序员极为熟悉的环境,并且简化了移植现有的基于套接口的应用程序源代码的工作。Windows Sockets API也是和4.3BSD的要求一致的。

1.3 Microsoft Windows和针对Windows的扩展
 这一套Windows Sockets API能够在所有3.0以上版本的Windows和所有Windows Scokets实现上使用,所以它不仅为Windwos Sockets实现和Windows Sockets应用程序提供了16位操作环境,而且也提供了32位操作环境。
 Windows Sockets也支持多线程的Windows进程。一个进程包含了一个或多个同时执行的线程。在Windows 3.1非多线程版本中,一个任务对应了一个仅具有单个线程的进程。而我们在本书中所提到的线程均是指在多线程Windows环境中的真正意义的线程。在非多线程环境中(例如Windows 3.0)这个术语是指Windows Sockets进程.
 Windows Sockets规范中的针对Windows的扩展部分为应用程序开发者提供了开发具有Windows应用软件的功能。它有利于使程序员写出更加稳定并且更加高效的程序,也有助于在非占先Windows版本中使多个应用程序在多任务情况下更好地运作。除了WSAStartup()和WSACleanup()两个函数除外,其他的Windows扩展函数的使用不是强制性的。

1.4 这份规范的地位
 Windows Sockets是一份独立的规范。它的产生和存在是为了造益于应用程序开发者,网络软件供应商和广大计算机用户。这份规范的每一份正式出版的版本(非草稿)实际上代表了为网络软件供应商实现所需和应用程序开发者所用的一整套API。关于这套规范的讨论和改进还正在进行之中。这样的讨论主要是通过Internet上的一个电子邮件论坛-winsock@microdyne.com进行的。同时也有不定期的会议举行。会议的具体内容会在电子邮件论坛上发表。

1.5 曾经作过的修改

1.5.1 Windows Sockets 1.0
 Windows Sockets 1.0代表了网络软件供应商和用户协会细致周到的工作的结晶。Windows Sockets 1.0规范的发布是为了让网络软件供应商和应用程序开发者能够开始建立各自的符合Windows Sockets标准的实现和应用程序。

1.5.2 Windows Sockets 1.1
 Windows Sockets 1.1继承了Windows Sockets 1.0的准则和结构,并且仅在一些绝对必要的地方作了改动。这些改动都是基于不少公司在创作Windows Sockets 1.0实现时的经验和教训的。Windows Scokets 1.1包含了一些更加清晰的说明和对Windows Sockets 1.0的小改动。此外1.1还包含了如下重大的变更:
 * 加入了gethostname()这个常规调用,以便更加简单地得到主机名字和地址。
 * 定义DLL中小于1000的序数为Windows Sockets保留,而对大于1000的序数则没有限制。这使Windows Sockets供应商可以在DLL中加入自己的界面,而不用担心所选择的序数会和Windows Scokets将来的版本冲突。
 * 增加了WSAStartup()函数和WASClearup()函数之间的关联,要求两个函数互相对应。这使得应用程序开发者和第三方DLL在使用Windows Sockets实现时不需要考虑其他程序对这套API的调用。
 * 把函数intr_addr()的返回类型,从结构in_addr改为了无符号长整型。这个改变是为了适应Microsoft C编译器和Borland C编译器对返回类型为四字节结构的函数的不同处理方法。
 * 把WSAAsyncSelect()函数语义从“边缘触发”改为“电平触发”。这种方式大大地简化了一个应用程序对这个函数的调用。
 * 改变了ioctlsocket()函数中FIONBIO的语义。如果套接口还有未完成的WSAAsyncSelect()调用,该函数将失败返回。
 * 为了符合RFC 1122,在套接口选项中加入了TCP_NODELAY这一条。
 所有Windows Sockets 1.1对于Windows Sockets 1.0的改动在以下都作了记号。


第二章 使用Windows Sockets 1.1编程
    在这一章,我们将介绍如何使用Windows Sockets 1.1编程,并讨论了使用Windows Sockets 1.1编程的一些细节问题。本章的讨论均是基于Windows Sockets 1.1规范的,在某些方面可能会和第六、七章对Windows Sockets 2的讨论不一致,请读者注意这一区别。

2.1 Windows Sockets协议栈安装检查
 任何一个与Windows Sockets Import Library联接的应用程序只需简单地调用WSAStartup()函数便可检测系统中有没有一个或多个Windows Sockets实现。而对于一个稍微聪明一些的应用程序来说,它会检查PATH环境变量来寻找有没有Windows Sockets实现的实例(Windows Sockets.DLL)。对于每一个实例,应用程序可以发出一个LoadLibrary()调用并且用WSAStartup()函数来得到这个实现的具体数据。
 这一版本的Windows Sockets规范并没有试图明确地讨论多个并发的Windows Sockets实现共同工作的情况。但这个规范中没有任何规定可以被解释成是限制多个Windows Sockets DLL同时存在并且被一个或者多个应用程序同时调用的。

2.2 套接口

2.2.1 基本概念
 通讯的基石是套接口,一个套接口是通讯的一端。在这一端上你可以找到与其对应的一个名字。一个正在被使用的套接口都有它的类型和与其相关的进程。套接口存在于通讯域中。通讯域是为了处理一般的线程通过套接口通讯而引进的一种抽象概念。套接口通常和同一个域中的套接口交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。Windows Sockets规范支持单一的通讯域,即Internet域。各种进程使用这个域互相之间用Internet协议族来进行通讯(Windows Sockets 1.1以上的版本支持其他的域,例如Windows Sockets 2)。
 套接口可以根据通讯性质分类;这种性质对于用户是可见的。应用程序一般仅在同一类的套接口间通讯。不过只要底层的通讯协议允许,不同类型的套接口间也照样可以通讯。
 用户目前可以使用两种套接口,即流套接口和数据报套接口。流套接口提供了双向的,有序的,无重复并且无记录边界的数据流服务。数据报套接口支持双向的数据流,但并不保证是可靠,有序,无重复的。也就是说,一个从数据报套接口接收信息的进程有可能发现信息重复了,或者和发出时的顺序不同。数据报套接口的一个重要特点是它保留了记录边界。对于这一特点,数据报套接口采用了与现在许多包交换网络(例如以太网)非常类似的模型。

2.2.2 客户机/服务器模型
 一个在建立分布式应用时最常用的范例便是客户机/服务器模型。在这种方案中客户应用程序向服务器程序请求服务。这种方式隐含了在建立客户机/服务器间通讯时的非对称性。客户机/服务器模型工作时要求有一套为客户机和服务器所共识的惯例来保证服务能够被提供(或被接受)。这一套惯例包含了一套协议。它必须在通讯的两头都被实现。根据不同的实际情况,协议可能是对称的或是非对称的。在对称的协议中,每一方都有可能扮演主从角色;在非对称协议中,一方被不可改变地认为是主机,而另一方则是从机。一个对称协议的例子是Internet中用于终端仿真的TELNET。而非对称协议的例子是Internet中的FTP。无论具体的协议是对称的或是非对称的,当服务被提供时必然存在“客户进程”和“服务进程”。
 一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务的地址提出了连接请求。在这个时刻,服务程序被“惊醒”并且为客户提供服务-对客户的请求作出适当的反应。这一请求/相应的过程可以简单的用图2-1表示。虽然基于连接的服务是设计客户机/服务器应用程序时的标准,但有些服务也是可以通过数据报套接口提供的。


2.2.3 带外数据
 注意:以下对于带外数据(也称为TCP紧急数据)的讨论,都是基于BSD模型而言的。用户和实现者必须注意,目前有两种互相矛盾的关于RFC 793的解释,也就是在这基础上,带外数据这一概念才被引入的。而且BSD对于带外数据的实现并没有符合RFC 1122定下的主机的要求,为了避免互操作时的问题,应用程序开发者最好不要使用带外数据,除非是与某一既成事实的服务互操作时所必须的。Windows Sockets提供者也必须提供他们的产品对于带外数据实现的语义的文挡(采用BSD方式或者是RFC 1122方式)。规定一个特殊的带外数据语义集已经超出了Windows Sockets规范的讨论范围。
 流套接口的抽象中包括了带外数据这一概念,带外数据是相连的每一对流套接口间一个逻辑上独立的传输通道。带外数据是独立于普通数据传送给用户的,这一抽象要求带外数据设备必须支持每一时刻至少一个带外数据消息被可靠地传送。这一消息可能包含至少一个字节;并且在任何时刻仅有一个带外数据信息等候发送。对于仅支持带内数据的通讯协议来说(例如紧急数据是与普通数据在同一序列中发送的),系统通常把紧急数据从普通数据中分离出来单独存放。这就允许用户可以在顺序接收紧急数据和非顺序接收紧急数据之间作出选择(非顺序接收时可以省去缓存重叠数据的麻烦)。在这种情况下,用户也可以“偷看一眼”紧急数据。
 某一个应用程序也可能喜欢线内处理紧急数据,即把其作为普通数据流的一部分。这可以靠设置套接口选项中的SO_OOBINLINE来实现(参见5.1.21节,setsockopt())。在这种情况下,应用程序可能希望确定未读数据中的哪一些是“紧急”的(“紧急”这一术语通常应用于线内带外数据)。为了达到这个目的,在Windows Sockets的实现中就要在数据流保留一个逻辑记号来指出带外数据从哪一点开始发送,一个应用程序可以使用SIOCATMARK ioctlsocket()命令(参见5.1.12节)来确定在记号之前是否还有未读入的数据。应用程序可以使用这一记号与其对方进行重新同步。
 WSAAsyncSelect()函数可以用于处理对带外数据到来的通知。

2.2.4 广播
 数据报套接口可以用来向许多系统支持的网络发送广播数据包。要实现这种功能,网络本身必须支持广播功能,因为系统软件并不提供对广播功能的任何模拟。广播信息将会给网络造成极重的负担,因为它们要求网络上的每台主机都为它们服务,所以发送广播数据包的能力被限制于那些用显式标记了允许广播的套接口中。广播通常是为了如下两个原因而使用的:1. 一个应用程序希望在本地网络中找到一个资源,而应用程序对该资源的地址又没有任何先验的知识。2. 一些重要的功能,例如路由要求把它们的信息发送给所有可以找到的邻机。
 被广播信息的目的地址取决于这一信息将在何种网络上广播。Internet域中支持一个速记地址用于广播-INADDR_BROADCAST。由于使用广播以前必须捆绑一个数据报套接口,所以所有收到的广播消息都带有发送者的地址和端口。
 某些类型的网络支持多种广播的概念。例如IEEE802.5令牌环结构便支持链接层广播指示,它用来控制广播数据是否通过桥接器发送。Windows Sockets规范没有提供任何机制用来判断某个应用程序是基于何种网络之上的,而且也没有任何办法来控制广播的语义。

2.3 字节顺序
 Intel处理器的字节顺序是和DEC VAX处理器的字节顺序一致的。因此它与68000型处理器以及Internet的顺序是不同的,所以用户在使用时要特别小心以保证正确的顺序。
 任何从Windows Sockets函数对IP地址和端口号的引用和传送给Windows Sockets函数的IP地址和端口号均是按照网络顺序组织的,这也包括了sockaddr_in结构这一数据类型中的IP地址域和端口域(但不包括sin_family域)。
 考虑到一个应用程序通常用与“时间”服务对应的端口来和服务器连接,而服务器提供某种机制来通知用户使用另一端口。因此getservbyname()函数返回的端口号已经是网络顺序了,可以直接用来组成一个地址,而不需要进行转换。然而如果用户输入一个数,而且指定使用这一端口号,应用程序则必须在使用它建立地址以前,把它从主机顺序转换成网络顺序(使用htons()函数)。相应地,如果应用程序希望显示包含于某一地址中的端口号(例如从getpeername()函数中返回的),这一端口号就必须在被显示前从网络顺序转换到主机顺序(使用ntohs()函数)。
 由于Intel处理器和Internet的字节顺序是不同的,上述的转换是无法避免的,应用程序的编写者应该使用作为Windows Sockets API一部分的标准的转换函数,而不要使用自己的转换函数代码。因为将来的Windows Sockets实现有可能在主机字节顺序与网络字节顺序相同的机器上运行。因此只有使用标准的转换函数的应用程序是可移植的。

2.4 套接口属性选项
 Windows Sockets规范支持的套接口属性选项都列在对setsockopt()函数和getsockopt()函数的叙述中。任何一个Windows Sockets实现必须能够识别所有这些属性选项,并且对每一个属性选项都返回合理的数值。每一个属性选项的缺省值列在下表中:

 选项           类型    含义                    缺省值    注意事项

 SO_ACCEPTCON   BOOL    套接口正在监听。        FALSE

 SO_BROADCAST   BOOL    套接口被设置为可以      FALSE
         发送广播数据。

 SO_DEBUG       BOOL    允许Debug。             FALSE      (*)

 S0_DONTLINGER  BOOL    如果为真,SO_LINGER     TRUE
         选项被禁止。

 SO_DONTROUTE   BOOL    路由被禁止。            FALSE      (*)

 SO_ERROR       int     得到并且清除错误状态。  0

 SO_KEEPALIVE   BOOL    活跃信息正在被发送。    FALSE

 SO_LINGER      struct  返回目前的linger信息。  l_onoff
       linger                          为0
       FAR *

 SO_OOBINLINE   BOOL    带外数据正在普通数据流  FALSE
         中被接收。

 SO_RCVBUF      int     接收缓冲区大小。        决定于实现  (*)

 SO_REUSEADDR   BOOL    该套接口捆绑的地址      FALSE
         是否可被其他人使用。

 SO_SNDBUF      int     发送缓冲区大小。        决定于实现  (*)

 SO_TYPE        int     套接口类型(如          和套接口被
         SOCK_STREAM)。         创建时一致

 TCP_NODELAY    BOOL    禁止采用Nagle      决定于实现
                              进行合并传送。

 (*) Windows Sockets实现有可能在用户调用setsockopt()函数时忽略这些属性,并且在用户调用getsockopt()函数时返回一个没有变化的值。或者它可能在setsocko

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值