1、Windows socket是Windows平台下为网络编程开放的一个接口。
它不是一种网络协议,是独立于协议的。它是以Unix socket为基础,因此Windows socket中的许多函数名与Unix都是一样的。除此之外它还允许开发人员充分利用Windows的消息驱动机制进行程序设计开发。
2、Windows Sockets API(WSA)包括一组函数调用、数据结构和约定。
WSA为所有Windows应用提供针对底层网络协议栈的网络服务的标准访问。
WinSock应用的任务:提供良好的任务界面,以及格式化数据并解析数据;
WinSock协议栈的任务:利用标准的传输协议、驱动程序和网络介质发送和接收这些数据。
3、WinSock网络模型:由三部分构成:WinSock应用程序。网络系统。WinSock API。
1)会话层和表示层:
文件传输协议FTP:文件传输。
简单邮件传输协议SMTP:电子邮件服务。
远程登录Telnet:用于远程登录的终端协商。
域名服务DNS:主机名到IP地址的映射。
2)传输层:
用户数据报协议UDP:无连接数据传输。
传输控制协议TCP:可靠的数据传输。
3)网络层:
因特网协议IP:独立于硬件的寻址、路由、分片和数据包重组。
地址解析协议ARP:IP地址到硬件地址的映射。
因特网控制消息协议ICMP:错误和控制消息。
4、WinSock API提供了对传输层和网络层协议服务(即网络系统)的访问。高层协议不能通过WinSock API访问,而是必须借助WInSock应用程序来实现。
RFC是一种文档,用来详细描述标准协议在实施中的要求和允许的操作。
5、套接字是应用层到运输层的接口,用以表示一条连接的两端。每一个端点由IP和端口组成。因此套接字由两端点的IP和端口组成。
端口是运输层的概念,每个端口对应一个进程,因此一条连接表示一个进程与另一个进程建立联系。
应用程序可以使用两种套接字。流套接字和数据包套接字,分别对应TCP和UDP。
1)TCP提供面向连接的可靠的、无重复、有序的数据流服务。TCP提供的是一个流,这意味着它按需向每个数据包中注入或多或少的数据。
2)UDP提供面向数据包的服务,不保证数据是可靠的、有序的和无重复的,也不反馈接收验证的确认信息。它采用TCP/IP标准的校验和算法(16位字的1的补码和)。保持数据分组边界不属于TCP的功能。
3)IP提供数据包的寻址、路由、分片和重组。寻址使数据包能够从一台IP主机传输到另一台IP主机,路由意味着为传输选择路径,分片和重组使大的IP数据包能够通过“小数据包”网络传输。这些服务中的大多数对Windows Sockets应用而言是完全透明的。
6、每个Windows Sockets应用都会用到的一个IP服务就是寻址,对于一个使用TCP/IP与另一台网络主机联系的网络应用,必须使用一个有效的IP地址。
1)构成可靠数据传输的服务要素有:
被确认的传输。错误检测。确认超时后重传。维持数据的顺序。无重复的数据。流量控制。
2)ICMP是一个“支持协议”,它不传输数据,只是传递控制、报错、通告一类的消息。WSAGetLastError( )函数返回的错误值提示所接收的ICMP消息类型。
例如,若返回WSAHOSTUNREACH错误,说明收到了ICMP的“主机不可达”的错误消息。
3)重定向和源抑制是控制消息,提供直接的数据包重路由和流量控制服务。前者是TCP/IP协议栈之间的低层控制消息,后者是为了通知UDP应用程序它发送数据报的速度太快了。
4)域名服务通过域协议实现。虽然域协议本身是透明的,但是应用程序可以通过调用主机名解析函数来直接访问其服务,这些函数是:gethostbyname( ),gethostbyaddr( ),WSAAsyncGetHostByName( )和WSAAsyncGetHostByAddr()。
7、在Windows环境下,使用Windows socket API进行网络程序开发时,需要调用Windows操作系统的Windows socket动态库。在应用程序中需要包含Windows sockets头文件。windows sockets 2.2版本需要包含WINSOCK2.h头文件(不区分大小写)。同时还需要添加动态库。
一种方法是在头文件中添加。如:
#pragma comment(lib,"WS2_32.lib")
另一种是在vc中添加。可以选择project ->settting,在link标签下添加wsock32.lib字符串。
8、客户端-服务器模型:
1)它们必须是同一种socket类型。要么都是流(TCP)类型,要么都是数据报(UDP)类型。
2)一个TCP/IP的socket名称包含IP地址、端口号以及协议。
当客户端socket成功联系上一个服务器端的socket时,两者的socket名称构成一个关联。
关联包含5个元素:
协议,客户端IP地址,客户端端口号,服务器IP地址,服务器端口号。
3)对于流类型,关联的生存期与虚电路的建立和撤销有关。大多数UDP应用程序在整个socket生存期中都使用同一个关联。
4)步骤:打开socket,命名socket,与另一个socket建立关联,在socket之间发送和接收数据。关闭socket。
5)在任何网络中,每一个关联都是唯一的。特定的关联决定了网络数据包的唯一性。它引导每个数据包在网络中的传输。关联两端的协议栈维持相关的信息,并把此信息插入在客户端与服务器之间所传输的每个网络层(IP)和传输层(TCP或UDP)数据单元的首部。接收端的协议栈利用其中的关联元素来识别其所属的socket。
9、Windows sockets中用定义的套接字类型SOCKET来表示套接字:
typedef unsigned int u_int;
typedef u_int SOCKET;
1)其实所谓的SOCKET的类型只不过是unsigned int的别名罢了。
2)INVALID_SOCKET表示一个无效的套接字,除此之外的0--INVALID_SOCKET-1都表示一个有效的套接字。因此在创建套接字后,都需要与INVALID_SOCKET比较,看创建的套接字是否有效。
10、Windows SOCKET可以支持多种不同的网络协议,并且提供与协议无关的编程接口。因此开发人员就可以相同的格式开发使用任一协议的网络应用程序,而不去关心各种协议的不同。
1)每种协议都有一套不同的IP定址方案(即表示主机地址的方式)。TCP协议和UDP协议通过IP协议传输数据。
而Windows SOCKET通过AF_INET地址家族为IP协议定址。
#define AF_INET 2
2)网络中每台主机都有一个IP地址,用32位数字来表示。TCP和UDP必须指定端口号。
在Windows SOCKET中sockaddr_in 结构被用来指定IP和端口号。
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
--sin_family表示地址族。使用TCP/IP协议的应用程序必须为aF_INET,来告诉系统使用IP地址家族 。
---sin_port指定服务的端口号。这个无符号的16位的值用以标识服务器所采用的应用层协议。1025--5000范围内的数据被作为服务端口号,可以由用户自定义。
---sin_addr的取值是为IP地址所设。调用bind( )函数时,它总是指向本地IP地址。
---sin_zero字段作为填充字段。以便使得该结构与SOCKADDR结构长度相同。
3)函数getservbyname( )和WSAsyncGetServName( )提供了从服务数据库中检索给定了服务名称的端口号的功能。
4)in_addr的定义如下:
struct in_addr {
union {
struct{
u_char s_b1,s_b2,s_b3,s_b4;
}S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
}
很显然它是一个存储IP地址的联合体,有三种表达方式:
第一种用四个字节来表示IP地址的四个数字;
第二种用两个双字节来表示IP地址;
第三种用一个长整型来表示IP地址。
5)给in_addr赋值的一种最简单方法是使用inet_addr函数,它可以把一个代表IP地址的字符串赋值转换为in_addr类型。
如 addrto.sin_addr.s_addr=inet_addr("192.168.0.2");
其反函数是inet_ntoa,可以把一个in_addr类型转换为一个字符串。
6)sockaddr类型是用来表示socket地址的类型,同上面的sockaddr_in类型相比,sockaddr的适用范围更广,因为sockaddr_in只适用于TCP/IP地址。
11、为了给socket命名 ,服务器会对socket的地址结构进行初始化,并调用bind( )函数。
sockaddr的定义如下:
struct sockaddr {
u_short sa_family; //地址族
char sa_data[14]; //根据地址族的值定义的地址结构数据区
};
可知sockaddr有16个字节,而sockaddr_in也有16个字节,所以sockaddr_in是可以强制类型转换为sockaddr的。事实上也往往使用这种方法。
1)不同cpu处理多字节时处理方式不同。Intel x86cpu对多字节的处理方式为高对高低对低。但是在网络上采用的是高对低,低对高的方式。因此也就存在所谓主机字节序和网络字节序的处理问题。
2)Htonl和htons函数实现主机字节顺序和网络字节序的转换功能。
H代表host,主机。N代表net。L代表long。S代表short。
注意:不要使用htonl转换short。
3)当然也有从网络字节序到主机字节序的转换函数:ntohl和ntohs。