![74af9265f78a587d54363b7491854df4.png](https://i-blog.csdnimg.cn/blog_migrate/daf20b5e4e9649b9e0eaab1917224023.jpeg)
socket技术详解
Date: 2019 / 06 /21
socket一词的起源
在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:“命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:“这比BSD的套接字接口定义早了大约12年。”
socket
要理解socket必须的得理解tcp/ip,它们之间好比送信的线路和驿站的作用, 所以我们简单地复习一下TCP/IP
funny
OSI模型
![be1f6117ff81f78813b582aa8484b5a1.png](https://i-blog.csdnimg.cn/blog_migrate/09b0dbe9a0efc1334f4f8a54e5ae3ad4.jpeg)
每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的
![9846cc2ac35d0ec395293fee5af0d3ae.png](https://i-blog.csdnimg.cn/blog_migrate/7ac3f6f5d8e9722f6798dfde4feec442.jpeg)
通过上面的图形,由于底一层的需要向高一层的提供服务,我们大致的理解应用程序需要传输层的tcp和网络层的ip协议提供服务,但是我们这章要分析的socket它是在tcpip协议的那一部分呢,就好比,我们的通讯线路已经有明确的规定,我们的驿站要设计在哪个地方一样。
细看
到目前为止,大致的了解了应用程序和tcpip协议的大致关系,我们只是知道socket编程是在tcp/IP上的网络编程,但是socket在上述的模型的什么位置呢?
funny
socket所在位置
![b64aff436299225a04d2ce60012689bc.png](https://i-blog.csdnimg.cn/blog_migrate/6626e602051fa72fe25fcba34f98540f.jpeg)
socket就在应用程序的传输层和应用层之间,设计了一个socket抽象层,传输层的底一层的服务提供给socket抽象层,socket抽象层再提供给应用层,问题又来了,应用层和socket抽象层之间和传输层,网络层之间如何通讯的呢?
通讯
要想理解socket编程怎么通过socket关键词实现服务器和客户端通讯,必须得实现的了解tcp/ip是怎么通讯的,在这个的基础上在去理解socket的握手通讯。
funny
TCP/IP通讯
在tcp/ip协议中,tcp通过三次握手建立起一个tcp的链接,大致如下:
第一次握手:客户端尝试连接服务器,向服务器发送syn包,syn=j,客户端进入SYN_SEND状态等待服务器确认。
第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
三次握手如图所示:
![192ef17d0901ef9bb8128696fab3ef04.png](https://i-blog.csdnimg.cn/blog_migrate/067732ebb9bcde8b8e6ec8dba058753e.jpeg)
根据tcp的三次握手,socket也定义了三次握手,也许是参考tcp的三次握手,
模型如下:
![383ea731be0f05feee3ac9362ef352ad.png](https://i-blog.csdnimg.cn/blog_migrate/1ae2ce609a2125b8842896feaa8c5871.png)
在上面图的基础上,如果我们得到上面的图形,需要我们自己开发一些接口,来满足上面的通讯的三次握手,问题就出来了,我们会需要开发哪些函数?
socket的一些接口函数原理
通过上面的图,我们清楚,我们好比一些泛型的程序员,一些理论提供者提供给了我们上面的图形的理论,我们需要做的就是讲上面的图形的抽象化的东西具体化。
第一次握手:客户端需要发送一个syn j 包,试着去链接服务器端,于是客户端我们需要提供一个链接函数
第二次握手:服务器端需要接收客户端发送过来的syn J+1 包,然后在发送ack包,所以我们需要有服务器端接受处理函数
第三次握手:客户端的处理函数和服务器端的处理函数
三次握手只是一个数据传输的过程,但是,我们传输前需要一些准备工作,比如将创建一个套接字,收集一些计算机的资源,将一些资源绑定套接字里面,以及接受和发送数据的函数等等,这些功能接口在一起构成了socket的编程。
下面大致的按照客户端和服务端将所需的函数详细的列举出来:
![5fd0f74a32e124c60c0ac807709c1413.png](https://i-blog.csdnimg.cn/blog_migrate/46ff1c4e3431861176853b3cfd880f62.png)
![7c1cc569eb71dda08cba90d3772e2cab.png](https://i-blog.csdnimg.cn/blog_migrate/47028fc279207a7aca1369b0b9f66bf7.jpeg)
上面的两个图都概述了socket的通讯原理
下面就介绍一些API函数:
创建套接字──socket()
调用格式如下:
SOCKET PASCAL FAR socket(int af, int type, int protocol)
指定本地地址──bind()
调用格式如下:
int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen)
建立套接字连接──connect()与accept()
调用格式如下:
int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen);
SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen);
监听连接──listen()
调用格式如下:
int PASCAL FAR listen(SOCKET s, int backlog);
数据传输──send()与recv()
调用格式如下:
int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags);
int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags);
输入/输出多路复用──select()
调用格式如下:
int PASCAL FAR select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout);
关闭套接字──closesocket()
调用格式如下:
BOOL PASCAL FAR closesocket(SOCKET s);
关注我们
![de4533ec85a078dfad7be5fd4155bab7.png](https://i-blog.csdnimg.cn/blog_migrate/bebbf7908a0549c9e3e4971e2aa5609a.jpeg)