网络套接字基础1-套接字
(一)网间进程通信怎么实现?
进程通信最初来源于本机进程之间,即单机系统。由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如管道(pipe)、命名管道(named pipe)软中断信号(signal),消息(message)、共享存储区(shared memory)和信号量(semaphore)等.
网间进程通信要解决的是不同主机进程间的相互通信问题(可把同机进程通信看作是其中的特例)。为此,首先要解决的是网间进程标识问题。同一主机上,不同进程可用进程号(process ID)唯一标识。但在网络环境下,各主机独立分配的进程号不能唯一标识该进程。例如,主机A赋于某进程号5,在B机中也可以存在5号进程,因此,“5号进程”这句话就没有意义了。 其次,操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不同。因此,网间进程通信还要解决多重协议的识别问题。
其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
使用TCP/IP协议的应用程序通常采用应用编程接口socket套接字,来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。
(二)Socket是什么?
套接字是网络间通信节点的抽象,编程者可以像操作文件一样实现网络通信.socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现.因此,当需要网络通信时,第一件事情自然就是创建一个用于通信的套接字啦.
TCP/IP协议族包括应用层/运输层/网络层/链路层,而socket所在位置如图,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,即是一组接口而已。
函数原型:
#include sys/socket.h
int socket(int domain, int type, int protocol);//返回sockfd
输入参数:
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET(IPV4)、AF_INET6(IPV6)、AF_UNIX,Unix域socket、AF_UNSPIC等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。当protocol为0时,会自动选择type类型对应的默认协议。
返回值:
返回创建的套接字描述符(socket descriptor),它唯一标识一个socket,失败返回-1.
函数原型:
#include unistd.h
int close(int fd);
在服务器与客户端建立连接之后,会进行一些读写操作,完成了读写操作就要关闭相应的socket描述字,好比操作完打开的文件要调用fclose关闭打开的文件。
(三)常用举例:
#include sys/socket.h
Int fd=-1;
Fd=socket(AF_INET,type,0); //创建一个套接字
If(fd<0) perror(“socket error!”);
.........//对套接字进行操作
Close(fd); //关闭一个套接字
注:socket用于网络通信的,只有套接字绑定一个地址才可以进行进程之间通信.