socket原理
1.socket socket位于应用层和TCP/IP协议通信中间,抽象成一组接口 1.服务端首先初始化Socket(),然后和接口进行绑定bind()和监听listen(),然后调用accept()进行阻塞。 2.客户端初始化socket(),然后调用connect()与服务端进行连接,然后客户端负责发送请求,服务端接收并且处理请求。write(),read().
2.socket的基本操作 1.socket()函数
int socket(int domain, int type, int protocol)
socket用于创建一个socket描述符,它唯一标识一个socket,包含了三个参数: 1.domain:协议域,常见的协议组用AF_INET AF_INET6 AF_LOCAL AF_ROUTE . 协议族决定了socket的地址类型,在通信中必须采用相应的地址.
2.type: 指定socket的类型. ps:socket的类型 根据数据的传输模式,可以将internet套接字分成两种模式. 流格式套接字(SOCK_STREAM):也称之为面向连接的套接字,是一种可靠的、双向的通信数据流.它的数据可以准确无误的到达另一台里算计,如果损坏或者丢失会重新发送.(使用TCP协议) 特点: 1.数据在传输过程中不会消失 2.数据按照顺序传输 3.数据的发送和接受不是同步的(流合适套接字内部用一个缓冲区)
数据报格式套接字(SOCK_DGRAM):也称之为无连接的套接字,计算机只负责传输数据,不进行数据校验.(使用UDP协议) 特点: 1.强调快速传输而非传输顺序 2.传输的数据可能丢失可能损毁 3,限制每一次传输的大小 4.数据的发送和接受是同步的
3.protocol:协议,常见的协议有IPPROTO_TCP、IPPTOTO_UDP、 IPPROTO_SCTP、IPPROTO_TIPC他们分别对应这TCP传输协议,UDP传输协议,STCP传输协议,TIPC传输协议.当protocol为0时,会自动选择type类型对应的默认协议.
2.bind()函数
int bind (int sockfd, const struct sockaddr * addr, socklen_t addrlen);
1.sockfd:即为socket描述字,他是通过socket()函数创建的,唯一标识一个socket.bind函数就是将这个描述子绑定一个名字
2.addr:一个const struct sockaddr*指针,根据创建地质结构根据地址创建socket时的地址协议不同而不同.
3.addrlen:对应地址的长度.通常服务器在启动时会绑定一个总所周知的地址(ip地址+端口号),客户端不用指定系统自动分配,所以通常服务端在listen之前要调用bind(),而客户端不会调用,在connect()时由系统随机生成一个.
网络字节序和主机字节序:
主机字节序: 1)大端存储:低位字节放在内存的低地址端,高位字节放在内存的高地址端 2)小端存储:低位字节放在内存的高地址端,高位字节放在内存的低地址端
网络字节序: UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节(即:高位字节存放在低地址处);由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的
将地址绑定到一个socket时,需要将主机字节序转换为网络字节序。
3.listen()函数、connect()函数
int listen(int sockfd, int backlog)
listen函数的第一个参数时即将要监听的socket描述字,第二个参数为相应的socket可以排队的最大连接数。socket()创建的socket默认是一个主动类型,listen则将socket变成被动类型,等待客户连接请求。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
connect函数的第一个参数是客户端socket的描述子,第二个参数是socket的地址,第三个函数是socket的地址的长度。客户端通过调用connect函数建立与TCP服务器的连接。
4.accept()函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept函数的第一个函数为服务器端的socket描述字,是服务器一开始调动socket()函数产生的,而accept函数返回的是已经连接的socket描述字。第二个参数用于返回客户端的协议地址,第三个表示地址的长度。
5.read(),write()等I/O读写函数
6.close()函数
int close(int fd)
close函数将对应的socket描述字的引用计数-1,当引用计数为0时,触发TCP客户端向服务器端发送终止连接请求。
7.TCP三次握手连接
1.客户端向服务器发送一个SYN 1 2.服务器向客户端发送一个SYN 2 ,并且对SYN 1 进行确认,ACK 1 + 1; 3.客户端向服务器确认 ACK 2 + 1
8.TCP四次挥手
1.客户端调用close主动关闭连接,向服务器端发送一个FIN 3
2.服务器端接受后,执行被动关闭,同时对FIN进行确认,ACK 3 +1 。同时它也作为文件结束符传递给应用程序。
3.一段时间后,接受到文件结束符的应用程序调用close关闭它的socket。同时服务器也发送一个FIN N。
4.接受到FIN的进行对服务器进行确认服务器端进行确认。
FIN_WAIT1 --------------
CLOSE_WAIT
FIN_WAIT2
-----------------------
LAST_ACK
-----------------------
CLOSE
TIME_WAIT
|