WinSockAPI

WinSock API简介

(一)实验目的

了解WinSock API的基本概念和用法

(二)实验内容

(1)TCP/IP协议简介

现在,TCP/IP协议已经成为了Internet的基础,它允许分布在各地的装着完全不同系统的计算机互相通信。
TCP/IP是一个四层协议:

图2.8.1 TCP/IP协议的体系结构

链路层:包括操作系统中的设备驱动程序和计算机中对应的网络接口卡,他们一起处理与电缆等传输媒介的物理接口细节。
网络层:该层负责传输数据。它需要确定的IP地址,以寻找路由。
传输层:该层主要为两台主机上的应用程序提供端到端的数据通讯。传输控制协议TCP提供质量保证的数据传输,负责数据的分组、质量控制和超时重发和包括将数据分割打包和组合。用户数据报协议UDP只提供简单的数据抱传输,在及时性服务中由重要的用途。
应用层:该层负责处理实际的应用程序细节,包括Telnet、Http、Ftp、SMTP等著名协议,也包括我们自己编写的网络应用程序。

(2)WinSock API简介

Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套Micosoft Windows下网络编程接口。Windows Sockets规范本意在于提供给应用程序开发者一套简单的API,并让各家网络软件供应商共同遵守。应用程序调用Windows Sockets的API实现相互之间的通讯。Windows Sockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。它们之间的关系如下图:

WinSock API是一套发展中的标准,已经发行了多个版本,目前最高版本为2.0,而我们主要讨论1.1版。

(3)套接字

套接字(Sockets)是通讯端点的一种抽象,它提供了一种发送和接收数据的机制。在Windows套接字中,它有两种形式,数据报套接字(Datagram Sockets)和流式套接字(Stream Sockets)。数据报套接字提供了一种不可靠的、无连接的数据包(packet)通信方式。在这里“不可靠”的意思是指发送一个数据包不能获得担保,也不能保证数据包按照放送的顺序到达。实际上,同一分组数据报可能不止一次的被发送。对于WinSock的TCP/IP实现,数据报套接字使用用户数据报协议(UDP协议);流式套接字提供了一种可靠的面向连接的数据传输方式,实现了无差错无重复的顺序数据传输。对于WinSock的TCP/IP实现,流式套接字使用传输控制协议(TCP协议)。

无连接服务器一般都是面向事务处理的,一个请求一个应答就完成了客户程序与服务程序之间的相互作用。若使用无连接的套接字(即数据报套接字)编程,程序的流程可以用下图表示:

面向连接服务器处理的请求往往比较复杂,不是一来一去的请求应答所能解决的,而且往往是并发服务器。使用面向连接的套接字(即流式套接字)编程,可以通过下图来表示其时序:

(4)字节顺序

字节以两种方式存储于一个字中,可使字节中的最高位位于字的左端(也称“大端法”),也可使字节中的最低位位于字的左端(也称“小端法”)。使用Intel x86体系结构的计算机使用小端法,而许多UNIX系统使用大端法。TCP/IP网络中公用字节顺序也是大端法(也称为“网络字节顺序”)。因此开发一个套接字应用时,需要进行字节顺序转换。下面是套接字字节顺序转换函数:
·htonl —— 将一个32位数从主机(host)字节顺序转换为网络(network)字节顺序
·htons —— 将一个16位数从网络(network)字节顺序转换为主机(host)字节顺序
·ntohl —— 将一个32位数从主机(host)字节顺序转换为网络(network)字节顺序
·ntohs —— 将一个16位数从网络(network)字节顺序转换为主机(host)字节顺序

(5)初始化和注销WinSock

WinSock API与其它Windows API有点不同,这一组API在使用前后必须进行初始化和清除,这样可以允许你和系统之间协商要使用的API的版本,并且系统可以返回你所使用的规范的一些有用的信息。使用WSAStartup()初始化WinSock,其第一个参数是一个WORD型数值,它指定了你的应用程序要使用的WinSock规范的最高版本。其中主版本号在低字节,辅版本号在高字节,通常使用WinSock 1.1版,即0x101;使用WSACleanup()注销WinSock。

(6)地址结构

地址结构sockadd_in用来指定一个IP地址和端口号,它是通用的sockaddr结构的Internet特定格式,通常需要强制转换为sockaddr类型,其结构如下:
  struct sockaddr_in
  {
    short sin_family; //必须为AF_INET
    unsigned short sin_port; //指定将要分配给套接字的端口号
    struct in_addr sin_addr; //分配给套接字的IP地址
    char sin_zero[8]; //为使该结构的大小与sockaddr匹配而加入的填充数
  }

端口号

大多数情况下,只是将数据包发送给给定地址的机器,例如202.38.64.1,是不足以确定到底要把数据包发送给机器的哪一个进程的。端口号允许你作更确定的指定。你的应用程序可以使用从1到65535之间的任何一个端口号,不过在选择端口时,必须特别小心,因为有些可用端口号是为“已知的”(即固定的)服务保留的(比如说文件传输协议和超文本传输协议,即FTP和HTTP)。“已知的协议”,即固定协议,采用的端口由“互联网编号分配认证(IANA)”控制和分配。端口号分为下面这三类:“已知”端口、已注册端口、动态和(或)私用端口。
■ 0 ~ 1023由IANA控制,是为固定服务(如FTP,HTTP,telnet,DNS等)保留的。
■ 1024 ~ 49151是IANA列出来的、已注册的端口,供普通用户的普通用户进程或程序使用。
■ 49152 ~ 65535是动态和(或)私用端口。
普通用户应用应该选择1024 ~ 49151之间的已注册端口,从而避免端口号已被另一个应用或系统服务所用。

IP地址

互联网上的每个接口(一台主机可以有几个接口)必须有一个唯一的Internet地址(也称作IP地址),IP地址长32 bit,这些32位的地址通常写成四个十进制的数,其中每个整数对应一个字节。这种表示方法称作“点分十进制表示法(Dotted decimal notation)”,例如202.38.64.1。
在WinSock中用结构in_addr表示IP地址。结构in_addr是4字节的,每个字节代表以点分隔形式的IP地址中的一个数字。比如对于IP地址1.2.3.4,它的表示形式会是0x04030201,可以用inet_addr()函数将用点分隔形式的十进制IP地址字符串转换成它,用inet_ntoa()完成相反的转换。一般用sin_addr.s_addr = htonl(INADDR_ANY)指定本机,也可以用127.0.0.1作为本机(LocalHost)的IP地址,即sin_addr.s_addr = inet_addr("127.0.0.1")。

(7)常用套接字函数

socket() 创建一个通讯端点并返回一个套接字。
  bind() 把指定的套接字同一个已知地址绑定起来。
  listen() 将套接字置入监听模式,指示套接字等候进入连接。
  accept()* 响应连接请求,返回一个与已接受连接对应的套接字。原来的套接字仍处于监听状态。
  connect()* 初始化到一个指定套接字上的连接。
  recv()* 从一个已连接的套接字接收数据。
  recvfrom()* 从一个已连接的或未连接的套接字接收数据。
  send()* 从一已连接的套接字发送数据。
  sendto()* 从已连接或未连接的套接字发送数据。
  closesocket() 关闭套接字,所有与其关联的资源都会被释放。

shutdown() 禁止在一个套接字上进行数据的接收与发送。
  select()* 确定一个或多个套接口的状态。
  ioctlsocket() 控制套接口的模式。ioctlsocket(s,FIONBIO,1)将套接字s设置成非阻塞模式。
  getpeername() 得到连接在指定套接口上的对等通讯方的名字。
  getsockname() 得到指定套接字上本地接口的地址信息。
  getsockopt() 得到与指定套接字相关的属性选项。
  setsockopt() 设置与指定套接字相关的属性选项。

*表示函数在应用于阻塞套接字时可能会阻塞。(套接字缺省为阻塞模式)

(8)套接字数据库函数

gethostbyaddr() 用IP地址获得对应主机的信息。
  gethostbyname() 用主机名获得对应主机的信息,包括IP地址。
  gethostname() 得到本地主机名。
  getprotobyname() 用协议名得到对应协议的信息。
  getservbyname() 从一个服务的名字得到对应服务的信息。
  getservbyport() 从一个端口号得到对应服务的信息。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值