常见的Socket技术-----伤痛
想到的几个库,还没有看,看得也不细,有点悲鸣!
——杰
Socket
- Socket原理
- TCP/IP协议
- 函数接口及原理
借鉴:socket技术
Socket原理
Socket简述
Socket,中文是“套接字”,是计算机之间进行通信的一种约定或者一种方式。通过socket,一台计算机可以准确的和多台计算机通信。
socket起源于Unix,Unix/Linux 基本哲学之一就是“一切皆文件”,都可以“打开-读写-关闭”模式。
Socket()函数返回一个整型的文件描述符,随后建立连接、数据传输等操作都是通过该函数实现。Socket的类型
有很多的socket,比如Unix socket.我们常见的是internet socket,根据数据的传输方式不同,可以分为两种类型。
流格式套接字(SOCK_STREAM)
面向连接的套接字,是一种可靠的、双向的通信数据流,可以准确无误的传输数据。(有自己的纠错机制)
特点:
数据在传输过程中不会消失;
数据是按照顺序传输的;
数据的发送和接收不是同步的 (其内部有一个缓冲区,用来传送和接收数据,他们的节奏是不同的)
举例:http协议
数据报格式套接字(SOCK_DGRAM)
无连接的套接字,只管传输数据,不作数据的校验,传输的效率高。(数据丢失,小概率事件)
特点:
强调快速传输而非传输顺序;
传输的数据可能丢失也可能损毁;
限制每次传输的数据大小;
数据的发送和接收是同步的。
总之,数据报套接字是一种不可靠的、不按顺序传递的、以追求速度为目的的套接字。
举例:QQ视频聊天
OSI 网络七层模型
七层模型,是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
TCP/IP模型,是应用层、传输层、网络层、望楼接口。
socket 编程,是站在传输层的基础上,所以可以使用 TCP/UDP 协议,但是不能干「访问网页」这样的事情,因为访问网页所需要的 http 协议位于应用层。
TCP/IP模型中,包含TCP、IP、UDP、Telnet、FTP等协议,也称为“TCP/IP”协议族
这里是socket编程的层次关系:
IP地址:“网际协议地址”,一台计算机可以拥有一个独立的IP地址,一个局域网也可以拥有一个独立的IP地址。
MAC地址:“局域网地址 LAN Address”。能真正唯一标识一台计算机。也可以修改,局域网中的路由器/交换机会记录每台计算机的 MAC 地址。
端口号:有了 IP 地址和 MAC 地址,虽然可以找到目标计算机,但仍然不能进行通信。为了区分不同的网络程序,计算机会为每个网络程序分配一个独一无二的端口号win下的socket编程:
服务端代码:
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dllint main(){//初始化 DLLWSADATA wsaData;WSAStartup( MAKEWORD(2, 2), &wsaData);//创建套接字SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);//绑定套接字sockaddr_in sockAddr;memset(&sockAddr, 0, sizeof(sockAddr)); //每个字节都用0填充sockAddr.sin_family = PF_INET; //使用IPv4地址sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址sockAddr.sin_port = htons(1234); //端口bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));//进入监听状态listen(servSock, 20);//接收客户端请求SOCKADDR clntAddr;int nSize = sizeof(SOCKADDR);SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);//向客户端发送数据char *str = "Hello World!";send(clntSock, str, strlen(str)+sizeof(char), NULL);//关闭套接字closesocket(clntSock);closesocket(servSock);//终止 DLL 的使用WSACleanup();return 0;
}
客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dllint main(){//初始化DLLWSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);//创建套接字SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);//向服务器发起请求sockaddr_in sockAddr;memset(&sockAddr, 0, sizeof(sockAddr)); //每个字节都用0填充sockAddr.sin_family = PF_INET;sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");sockAddr.sin_port = htons(1234);connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));//接收服务器传回的数据char szBuffer[MAXBYTE] = {0};recv(sock, szBuffer, MAXBYTE, NULL);//输出接收到的数据printf("Message form server: %s\n", szBuffer);//关闭套接字closesocket(sock);//终止使用 DLLWSACleanup();system("pause");return 0;
}
大致的编程流程是:
加载stdlib.h和winsock2.h头文件,还有ws2_32.dll,然后初始化dll,创建套接字,定义数据传输类型。再向服务器发起请求,将一段内存块中进行清零,确定输入IP,端口,然后连接。接收服务器传回的数据,定义一个缓冲区数组,recv接受数据。输出接收的数据,关闭套接字和dll。
socket(int af, int type, int protocol),创建套接字。其中af,指IP地址;type指数据传输类型;protocol,传输协议。
TCP/IP协议
- TCP/IP【TCP(传输控制协议)和IP(网际协议)】提供点对点的链接机制,将数据应该如何封装、定址、传输、路由以及在目的地如何接收,都加以标准化。
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接,客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。
TCP建立连接时要传输三个数据包,俗称三次握手
数据的“粘包”问题,客户端发送的多个数据包被当做一个数据包接收。也称数据的无边界性,read()/recv() 函数不知道数据包的开始或结束标志(实际上也没有任何开始或结束标志),只把它们当做连续的数据流来处理。
数据结构
(1) 序号:Seq(Sequence Number)序号占32位,用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。
(2) 确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。
(3) 标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN,三次握手(建立连接的过程):
用自己的话来表述:
客户端向服务端请求连接,发送一个数据包,里面有自己的序列号;服务端接受到后,返回一个确认号,发送一个数据包,里面有自己的序列号;客户端接收到后,回复一个确认号。
- 四次握手(断开连接)
用自己的话来描述:
客户端调用close()函数,向服务端发送一个fin数据包,包含序列号,请求断开连接;服务端收到后,回复确认;客户端收到后,进入fin_wait_2状态;服务端准备完毕后,发送一个fin包;客户端收到后,回复一个ACK关闭客户端;服务端收到后断开。
- 关于 TIME_WAIT 状态的说明
客户端最后一次发送 ACK包后进入 TIME_WAIT 状态,而不是直接进入 CLOSED 状态关闭连接,这是为什么呢?
TCP 是面向连接的传输方式,必须保证数据能够正确到达目标机器,不能丢失或出错,而网络是不稳定的,随时可能会毁坏数据,所以机器A每次向机器B发送数据包后,都要求机器B”确认“,回传ACK包,告诉机器A我收到了,这样机器A才能知道数据传送成功了。如果机器B没有回传ACK包,机器A会重新发送,直到机器B回传ACK包。
客户端最后一次向服务器回传ACK包时,有可能会因为网络问题导致服务器收不到,服务器会再次发送 FIN 包,如果这时客户端完全关闭了连接,那么服务器无论如何也收不到ACK包了,所以客户端需要等待片刻、确认对方收到ACK包后才能进入CLOSED状态。那么,要等待多久呢?
数据包在网络中是有生存时间的,超过这个时间还未到达目标主机就会被丢弃,并通知源主机。这称为报文最大生存时间(MSL,Maximum Segment Lifetime)。TIME_WAIT 要等待 2MSL 才会进入 CLOSED 状态。ACK 包到达服务器需要 MSL 时间,服务器重传 FIN 包也需要 MSL 时间,2MSL 是数据包往返的最大时间,如果 2MSL 后还未收到服务器重传的 FIN 包,就说明服务器已经收到了 ACK 包
- 优雅的断开连接–shutdown()
close()/closesocket() 会立即向网络中发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()/closesocket() 将丢失输出缓冲区中的数据,而调用 shutdown() 不会
函数接口及原理
- socket()函数创建套接字
socket(int af, int type, int protocol);
- socket() 函数用来创建套接字,确定套接字的各种属性,然后服务器端要用 bind() 函数将套接字与特定的IP地址和端口绑定起来。
bind(int sock, struct sockaddr *addr, socklen_t addrlen)
sock 为 socket 文件描述符,addr 为 sockaddr 结构体变量的指针,addrlen 为 addr 变量的大小,可由 sizeof() 计算得出
- 使用 bind() 绑定套接字后,还需要使用 listen() 函数让套接字进入被动监听状态,再调用 accept() 函数,就可以随时响应客户端的请求。
listen(int sock, int backlog)
sock 为需要进入监听状态的套接字,backlog 为请求队列的最大长度
常见的Socket技术-----伤痛相关推荐
- 系统接口规范以及常见的接口技术概述和比较
系统接口规范以及常见的接口技术概述和比较 一.基本要求: 为了保证系统的完整性和健壮性,系统接口应满足下列基本要求: 1.接口应实现对外部系统的接入提供企业级的支持,在系统的高并发和大容量的基础上提供 ...
- 工业计算机远程控制,基于SOCKET技术的计算机远程控制实现
摘要:时至今日,计算机网络已经成为了人类社会生活中必不可少的组成部分,其中计算机的远程控制系统更是为整个社会的进步起到推动作用.除了在工业自动化生产之外,计算机远程控制系统还广泛的应用于办公.技术支持 ...
- linux下图片加密原理,Linux中常见的加密技术介绍
常见的加密技术: 对称加密:非对称加密:单向加密:SSL/TLS:秘钥交换 1.对称加密 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密 ...
- 常见的穿透技术有哪些?
问题描述: 用户不了解常见的用于视频会议产品的穿透技术 详情解答: 常见的穿透技术有:STUN.TURN.ICE 一.STUN STUN协议为终端提供一种方式能够获知自己经过NAT映射后的地址,从而替 ...
- 网络攻防---常见的网络攻击技术及其原理
听课笔记--网络攻击与防御--常见的网络攻击技术及其原理 1.网络攻击的一般步骤 2.攻击前奏 3.实施攻击 一.网络攻击的一般步骤 1.确定攻击目标Targeting 2.信息收集 Informat ...
- 常见室内定位技术对比,你了解吗?
常见室内定位技术对比,你了解吗? 1 室内定位技术对比 定位技术 定位精度 可靠性 成本 安全性 蓝牙 3m 中 高 中 红外线 5m 低 高 高 射频技术 5m 中 低 中 WIFI 3m ...
- Flink常见的关键技术与特性详解
转载:http://bigdata.51cto.com/art/201702/531036.htm Flink常见的关键技术与特性详解 Flink项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其 ...
- Linux系统漏洞复现分析,Linux环境下常见漏洞利用技术
记得以前在drops写过一篇文章叫 linux常见漏洞利用技术实践 ,现在还可以找得到(https://woo.49.gs/static/drops/binary-6521.html), 不过当时开始 ...
- 端到端加密优缺点_网络通信中常见的数据加密技术探析
前言 目前在各行各业中都广泛使用计算机网络通信技术,计算机网络已成为人们生活中不可或缺的重要内容,人们对计算机网络的依赖性不断提高,计算机网络通信的安全性受到越来越多的关注.数据加密技术是保障计算机网 ...
- 常见的定位技术主要有哪些?
目前,常见的定位技术主要有:蓝牙.RFID.WIFI.超宽带(UWB).超声波等.智物达"智寻"超宽带(UWB)定位系统是一种以极低功率在短距离内高速传输数据的无线定位技术. UW ...
最新文章
- javascript中构造函数的返回值问题和new对象的过程
- muduo网络库学习(七)用于创建服务器的类TcpServer
- Java学习进阶—高级编程
- Github Action 快速构建 Electron 应用
- mysql查看sql代价_mysql 代价
- 在MacBook上Jupyter安装
- rgmanager 介绍
- html 获取本机ip_爬取快代理免费ip,构建自己的代理ip池,不再怕反爬(附代码)...
- java基础总结06-常用api类-Object和Objects
- linux电路图软件有哪些,新手福利,推荐一款好用的电路图绘制软件!
- 5款开源BI系统倾力推荐,企业信息化的利器
- 经典~吸引力法则:你相信什么,就会吸引什么,获得什么
- 合并多个集合同类项{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}通过编程实现结果为:{aaa,bbb,ccc,ddd,hhh},{eee,fff},
- MLC转成SLC模式没有想象的那么好
- 光伏箱变保护测控装置
- 玩安卓从 0 到 1 之项目总结
- img标签src引入svg如何修改颜色
- dva去掉访问路径中的“#”
- codeforces EDU suffix array
- 打造高安全数字基础设施:中国电子云服务关键行业的宣言