什么是Socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API)。
俗称套接字
他介与应用层和传输层之间
IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层。
TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
Socket自定义传输
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
下面是流程图

一.开启服务器ServerSocket
对于我们的Mac来说开启nc netcat 打卡命令行输入nc -lk 端口号

socket() -->bind() -- >listen()-- accpet() -- 客户端和服务器开始读写操作 -- 收到客户端关闭连接请求消息--->关闭连接
bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)
struct sockaddr_in 通过这个结构里面内容捆绑接口下面会描述这个接口
listen() 创建一个套接口并监听申请的连接
我这篇文章主要实现客户端的请求实现
二.客户端连接请求
第一步创建socket
创建socket (导入对应的头文件<netinet/in.h>,<sys/socket.h>,<arpa/inet.h>)
socket(int, int, int)
第一个参数 协议域 AF_INET(ipv4)、AF_INET6(ipv6)....
第二次参数:指定Socket类型。常见的2种
sock_stream是基于TCP的 是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送。
sock_dgram 是基于UDP的, 是无保障的面向消息的socket , 主要用于在网络上发广播信息。
第三个次参数:指定协议 IPPROTO_TCP IPPROTO_UDP

第二步创建连接
connect(int, const struct sockaddr , socklen_t) (经过3次握手)
参数一:套接字描述符
参数二: struct sockaddr_in
参数三:参数二sockaddr的长度,可以通过sizeof(struct sockaddr)获得
sockaddr 结构体

第三步发送消息
s:一个用于标识已连接套接口的描述字。
buf:包含待发送数据的缓冲区。
len:缓冲区中数据的长度。
flags:调用执行方式。一般填0
send(<#int#>, <#const void *#>, <#size_t#>, <#int#>)

第四部接收消息
recv(int, void *, size_t, int)

我模拟了一个聊天的效果
启动了一个定时器每过一段时间去取一次数据.模拟聊天

值得注意的是recv 使用了堵塞的方式获取数据,所以把他放在子线程去做数据的接收
第五步关闭连接
close(int)

我将socket的创建,连接,发送,接收,和关闭封装到一个类里面进行操作
建立连接和接收服务器数据
本地回环地址建立服务器的连接,连接6969端口

发送数据

请求到数据的结果

模拟发送http的请求
通过命令行 获取网址的地址

一般的端口号都是80

接收数据

接收数据的具体实现

使用socket 发送http网络请求 App Transport Security Settings 可以绕过安全协议的限制,说明我们高级NSURLSession 对是否遵守这个权限做了判断
OSI七层模型
应用层
网络服务与最终用户的一个接口。
协议有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP
表示层
数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层)
格式有,JPEG、ASCll、DECOIC、加密格式等
会话层
建立、管理、终止会话。(在五层模型里面已经合并到了应用层)
对应主机进程,指本地主机与远程主机正在进行的会话
传输层
定义传输数据的协议端口号,以及流控和差错校验。
协议有:TCP UDP,数据包一旦离开网卡即进入网络传输层
网络层
进行逻辑地址寻址,实现不同网络之间的路径选择。
协议有:(最主要的主要)IP(IPV4 IPV6) ICMP IGMP ARP RARP
数据链路层
建立逻辑连接、进行硬件地址寻址、差错校验 等功能。
将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。
物理层
建立、维护、断开物理连接。(由底层网络定义协议)
后言:
我们开发过程中一般都是用更加高级的api,写一点底层的是帮助我们理解客户端和服务器的通讯过程,过年了梳理下知识点
网友评论