!!接下来要介绍的Socket函数都是和操作系统无关的,即不管是在Unix、Linux、Mac OS X还是Windows,这些函数都是标准版本的,可以在任意平台上使用,并且都是C语言版的;
1. Socket套接字的概念:
1) 套接字这个名称的背景:
i. 拿最早的电话机来讲,刚有电话的时候如果想拨通另一端的电话,需要电话公司将两个电话所对应的插头插入两个线路互通的插孔中,而套接字就是这种插孔了;
ii. 套接字其实应该叫“套字接”,即理解为“包着字节的接口”,由于计算机互联的协议都是字型协议(即字节、字的那种字),而应用程序只要插进该接口就可以和其它也插入该接口的应用程序进行通信;
iii. Socket的英文翻译就是“建立在一种平台或机器上的插孔,用于连接两个电器设备使之能相互通信”,也就是说Socket可用于任何两个电子设备之间的信息通信,不管使用的是什么协议(HTTP、TCP、UDP等),都要使用Socket通信;
2) 今后,就将Socket称作网络通信接口,也就是说Socket编程实质上就是一种接口编程;
2. 如何确定一个套接字呢?——套接字的寻址方式
1) 和电话网类似,两个人要交流,首先需要知道两个人的地址才行,因此套接字中一定包含通信双方的网络地址,如果使用的是TCP/IP协议,则该地址就是IP地址,如果是其它协议,则地址则会是其它模式;
2) 但计算机的相互通信实质上是两台计算机中的应用程序在进行通信,比如用uto下载文件,那实质上就是两台电脑的uto之间进行信息交换,因此IP只是确定了计算机的地址,但还需要另一个参数来确定参与通信的到底是哪个应用程序,该参数就是端口号,因此套接字里还封装了端口号;
3) 通信双方各持有一个套接字,各套接字封装了各自的网络地址和端口号,双方应用程序只要绑定了各自的套接字就能进一步通信 了;
4) 以上确定套接字的方法就是套接字的寻址方式;
3. 寻址方式的代码实现:
1) 即套接字地址结构,就理解为网络通信接口的地址:
struct sockaddr_in { // 套接字地址
short sin_family; // 指定是哪种地址家族
unsigned short sin_port; // 端口号
struct in_addr sin_addr; // 网络地址,如IP地址等,有sin_family决定
char sin_zero[8]; // 无用,为了兼容第一代Socket版本,全设为0
};
i. sockaddr_in:即Socket Address - internet的缩写,即网络接口地址的意思,注意internet的i是消息而不是大写,即表示普通的网络而不是Internet英特网!
ii. sin_:该前缀就是Socket internet的缩写;
iii. sin_family:即地址家族,是指上隐含指定了使用的是哪种协议,如果是使用基于IP地址的TCP、UDP协议等,就将这项设为AF_INET,即Address Family internet的缩写,即互联网地址家族;
2) in_addr结构:该结构确定了套接字的网络地址,如IP地址等,也可以是其它地址,这取决于sin_family
struct in_addr { // 网络地址
union {
struct { u_char s_b1, s_b2, s_b3, s_b4 } S_un_b; // 4字节版本
struct { u_short s_w1, s_w2 } S_un_w; // 2字版本
u_long S_addr // 1双字版本
} S_un;
};
i. 地址一定是32位的,为了编程需要,有时需要分别对地址中的字节、字等进行操作,避免程序员使用麻烦的位操作,从而利用联合体给出了字节、字、双字的三个版本,可以是编程更加灵活;