通过套接字可以实现不同计算机(通过网络连接)上运行的进程相互之间的通信。
socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议。门面模式,简单说就是系统对外界提供单一的接口,外部不需要了解内部的实现。
socket是分布式、云计算、网络编程的基础,对socket的学习有助于对其他框架的理解。跨平台网络编程框架,如Java的SSH(Struts流程控制、Spring业务转流、Hibernate数据库操作封装),C/C++的ACE、livevent和Boost。分布式框架,如Hadoop等。
1套接字
1.1创建套接字
套接字是通信端点的抽象,访问套接字也需要用套接字描述符。
头文件 |
#include <sys/socket.h> |
||||||||
函数原型 |
int socket(int domain,int type, int protocl); |
||||||||
参数 |
domain:域或地址族,确定通信的特性。
多数系统还会定义AF_LOCAL域,这是AF_UNIX的别名。AF_UNSPEC域可以代表任何域。 type:类型,确定套接字的类型,进一步确定通信特征。
SOCK_SEQPACKET套接字和SOCK_STREAM套接字类似,但从该套接字得到的是基于报文的服务而不是字节流服务。流控制传输协议(SCTP)提供了因特网域上的顺序数据包服务。 SOCK_RAW套接字提供一个数据报接口用于直接访问下面的网络层(在因特网域中为IP)。使用这个接口时,应用程序负责构造自己的协议首部,这是因为传输协议(TCP和UDP等)被绕过了。当创建一个原始套接字时需要有超级用户特权,用以防止恶意程序绕过内建安全机制来创建报文。 protocol:通常是0,表示按给定的域和套接字类型选择默认协议。 AF_INET通信域中套接字类型为SOCK_STREAM的默认协议是TCP。 AF_INET通信域中套接字类型为SOCK_DGRAM的默认协议是UDP。 当对同一域和套接字类型支持多个协议时,可以使用protocol参数选择一个特定协议。 |
||||||||
返回 |
成功返回套接字描述符,出错返回-1。 |
||||||||
功能 |
创建一个套接字 |
关闭套接字
头文件 |
#include <unistd.h > |
函数 |
int close(int filedes); |
参数 |
filedes:套接字描述符 |
返回值 |
成功返回0,出错返回-1 |
功能 |
关闭套接字,并且释放该描述符以便重新使用。 |
套接字通信是双向的,可以采用函数shutdown来禁止套接字上的输入/输出。
头文件 |
#include <sys/socket.h> |
函数 |
int shutdown(int sockfd, int how); |
参数 |
sockfd:套接字描述符 how: SHUT_RD 关闭读端,不能从套接字读取数据 SHUT_WR 关闭写端,不能用套接字发送数据 SHUT_RDWR关闭读写,套接字无法读取和发送数据 |
返回值 |
成功返回0,出错返回-1 |
功能 |
禁止套接字上的输入/输出 |
能够用close关闭套接字,还使用shutdown的理由:
首先,close只有在最后一个活动引用被关闭时才释放网络端点。这意味着如果复制一个套接字(如采用dup),套接字直到关闭了最后一个引用它的文件描述符之后才会被释放。
Shutdown允许使用一个套接字处于不活动状态,无论引用它的文件描述符数目多少。其次,有时只关闭套接字双向传输中的一个方向会很方便。如,如果想让所通信的进程能够确定数据发送何时结束,可以关闭该套接字的写端,然而通过该套接字读端仍可以继续接收数据。
1.2套接字与地址绑定
如何确定一个目标通信进程?进程的标识有两个部分:计算机的网络地址可以帮助标识网络上想与之通信的计算机,而服务可以帮助标识计算机上特定的进程。
<1>字节序