最后更新:2021-12-04 17:25:05 手机定位技术交流文章
目录
1. 概念
1. 网络设计模式
- B/S
- C/S
- IP和端口
- 基于OSI/ISO的网络分层模式
2. 协议格式
三. 用插座编程
3.1 字节序
- 接口转换函数
3.2 IPIP地址转换
储存附加数据结构为3.3。
3.4 套接字函数
四、TCP来文程序
tcp 服务器服务器-服务器通信过程 :
tcp 客户阴蒂通讯程序如下:
1. 概念
1. 网络设计模式
- B/S
- 客户:网络浏览器
- 服务器:服务器
跨平台兼容性和低廉的开发成本是其主要优势。
劣势:
是的,它已得到更正:https, https
无法关闭临时文件夹:%s。
- C/S
- 客户:桌面程序
- 后台服务器
好处包括能够处理大量的磁盘数据。
缺点:如果你跨过平台,你必须付出巨大的代价重建平台。
- IP和端口
- IP地址
- IPV4
- 实际是一个32位的整形数 -> 本质 -> 4字节 int a;
- 我们看的的不是这个整形数, 点分十进制字符串 -> 192.168.247.135
- 分成了4份, 每份1字节, 8bit -> char , 最大值为 255 -> 最大取值: 255.255.255.255
- 有几个IP地址?
- IPV6
- 事实上,这是一个128位数的矫形号码
- xxx:xxx:xxx:xxx:xxx:xxx:xxx:xxx , 分成了8分, 每份16位 -> 每一部分以16进制的方式表示
- 有几个IP地址?
- IP地址的作用:
我们可以使用IP地址找到主机
- 端口
-主机有很多程序在运行
- 向东道方进程提供数据
- 程序如果要联网,可以与港口连接。
- 有了这个港口,我们可能会决定一个过程
- 端口号: unsigned short int -> 16位
- 提取港口范围:0 - 65535(216)
- 基于OSI/ISO的网络分层模式
> OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,是ISO(国际标准化组织组织)在1985年研究的网络互联模型。
- 七层模型
底层 --------->上层
信息应以下列方式在互联网上传播:
> - 物理层:
> - 物理层负责最后将信息编码成电流脉冲或其它信号用于网上传输
> - 数据链路层:
> - 数据链路层通过物理网络链路供数据传输。
> - 规定了0和1的分包形式,确定了网络数据包的形式;
> - 网络层
> - 网络层负责在源和终点之间建立连接;
> - 此处需要确定计算机的位置,怎么确定?IPv4,IPv6
> - 传输层
> - 传输层向高层提供可靠的端到端的网络数据流服务。
> - 每一个应用程序都会在网卡注册一个端口号,该层就是端口与端口的通信
> - 会话层
> - 会话层建立、管理和终止表示层与实体之间的通信会话;
> - 建立一个连接(自动的手机信息、自动的网络寻址);
> - 表示层:
> - 对应用层数据编码和转化, 确保以一个系统应用层发送的信息 可以被另一个系统应用层识别;
> - 可以理解为:解决不同系统之间的通信,eg:手机上的QQ和Windows上的QQ可以通信;
> - 应用层:
> - 规定数据的传输协议
四层模型
2. 协议格式
三. 用插座编程
套接字通信分为两部分:
- 服务器端:被动连接接受,而不是主动连接启动
- 客户通信:与服务器建立连接。
Socket是Linux和Windows都可以使用的通信界面的集合,但变化不大。
3.1 字节序
如名称所示,字节顺序是指将字节类型的数据存储在内存中的顺序。
- 概念
- Little-Endian -> 主机字节序
- 在内存中保存一个数据点:0x12345678。
- 内存低地址存储数据以低字节储存,而内存高地址存储数据以高字节储存。
- Big-Endian -> 网络字节序
- 内存低地址数据储存字节、内存高地址数据储存字节
- 字节序举例
为了表示这两个整数,请使用16点内存,即:
- 0x12 34 56 78 -> 四字节 char -> 255 -> ff
- 0x11223344 -> 四字节
- 小端
低地址位 -------------> 高地址位
0x78 0x56 0x34 0x12
0x44 0x33 0x22 0x11
- 大端
低地址位 -------------> 高地址位
0x12 0x34 0x56 0x78
0x11 0x22 0x33 0x44
- 接口转换函数
BSD Socket 提供一种密封的转换界面,程序员可以随时访问。
htons 和 htonl 是网络 byte (n) 转换例行程序的主机 byte (h) 。
以下函数将网络字节(n)转换为主机字节(h):nohs,nothl。
#include <arpa/inet.h>
// shot int -> 4字节(64位)
// h -> host
// n -> network
// s -> short
// l -> long
// xtoxs() -> 进行端口转换
uint16_t htons(uint16_t hostshort);
参数: 主机字节数的short型数值 -> 要转换的数(主机)
转换后获得的数据(网络字节顺序)为返回值
uint16_t ntohs(uint16_t netshort);
// long -> 8字节(64位)
// xtoxl() -> 进行IP转换
uint32_t htonl(uint32_t hostlong);
uint32_t ntohl(uint32_t netlong);
3.2 IPIP地址转换
#include <arpa/inet.h>
(小数字符串中的点)
// p -> 点分十进制字符串 IP
// n -> network
// 将主机字节序的 字符串IP -> 网络字节序的 整形数
int inet_pton(int af, const char *src, void *dst);
参数:
- 如果满足下列条件:地址家庭协议、IPv4、IPv6
ipv4: AF_INET, ipv6:AF_INET6
-src:指向字符串 IP 地址
- dst: 传输参数, 执行内存地址, 并记录此内存中已转换网络字节的整数 。
返回值:
-1: 失败
1: 成功
0: 查字典
// 网络字节序的整形IP -> 点分十进制字符串 IP
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
参数:
- 如果满足下列条件:地址家庭协议、IPv4、IPv6
ipv4: AF_INET, ipv6:AF_INET6
- src: 指向要转换的网络字节顺序的可选 IP 地址 。
- dst: 当转换完成时保存点的位置 。
- 大小:经修改后为与第三个 dst 参数相关的内存大小。
返回值:
NULL: 失败
一个非空的指针指向三根手指的记忆:
储存附加数据结构为3.3。
对于网络连接,则使用结构套装机和套装机。
用于进程间通信,使用 sockaddr_un 结构。
IPv6 通信的 sockaddr_ in 结构
由于结构套装机需要用手指切换来添加IP地址,这很难,在现实中,我们使用套装机来添加端口号码和 IP 地址。 转换成套装机型会得到加强, 因为两个结构的大小相同, 而后端服务器客户程序也会被提供 。
struct sockaddr {
sa_ family_t sa_ family; / ipv4, ipv6 地址家庭协议
char sa_data[14];
}
struct sockaddr_in
{
IP选择 AF_INET( Ipv4) 和 AF_INET6( Ipv6) 。
(网络字节顺序: htons ()), in_port_t sin_port
IP 位址( 网络字节顺序: inint_ pton () ), 以 _ addr sin_ addr 的 Struct
//预留空间:
unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) - sizeof (struct in_addr)];
};
struct in_addr
{
IP 地址 (网络字节顺序: inint_pton ()), in_addr_t s_addr
};
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
typedef unsigned short int sa_family_t;
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
3.4 套接字函数
#include <arpa/inet.h>
做一个套接字
int socket(int domain, int type, int protocol);
参数:
- 域域:关于地址家庭的协议
AF_INET: ipv4
AF_INET6: ipv6
AF_UNIX,AF_LOCAL 本地共享(流程间通信)
- 议定书:一种通讯议定书
SOCK_STREAM:适应协议
SOCK_DGRAM 是新闻协议 。
- 一般而言,协议:0。
- SOCK_STREAM:适应协议默认使用使用: tcp
- SOCK_DGRAM 是新闻协议 。默认使用使用: udp
返回值:内核缓冲由此文件描述符管理。
成功: 文件描述符 > 0
失败: -1
// 绑定函数 -> 将fd 和本地的 IP + Port进程绑定
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
- 套接字功能 - 套接字功能 - A sockfdd:
这一结构必须与IP和Port一起初始化。
- 内存结构的第二个参数
// 设置监听
int listen(int sockfd, int backlog); // /proc/sys/net/core/somaxconn
参数:
- 套接字功能 - 套接字功能 - A sockfdd:
- 后向: 连接成功, 但是为未处理连接请求的值不能超过 / proc/ sys/ net/ core/ somaxconn 中记录的数据, 默认情况下该数据为 128 。
/ 默认是一个屏蔽功能, 暂停等待客户端请求。 请求到达、 客户端连接和文件描述
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
- Sockfd: 正在监听文件描述符( 设置)
- 添加:为了连接到成功的客户端,提供参数并记录IP和端口信息。
第二个参数结构的内存大小。
返回值:
- 成功: 通信的文件描述符 > 0
- 失败: -1
此函数被客户端用于连接到服务器 。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
- Sockfd: 通信文件说明
- Addr: 客户端想要连接的服务器地址 。
- 内存结构的第二个参数
返回值:
连接成功: 0
连接失败: -1
// 写数据
ssize_t write(int fd, const void *buf, size_t count);
// 读数据
ssize_t read(int fd, void *buf, size_t count);
四、TCP来文程序
// tcp / udp-> 传输层协议
TCP代表“连接、安全、当前传输协议”。
- 我们不会失去数据
udp: 无连接、 危险、 报告传输协议
tcp 服务器通信方法 :
一,做一个监听插座
- 倾听:注意客户的联系。
文件描述符是一个插座。
二. 将监听文件的说明连接到本地IP和端口(IP和端口=服务器地址信息)。
- 当客户端连接到服务器时,使用IP地址和端口。
三,当你安装窃听器时,窃听器开始运作。
四. 当客户开始连接时,它会解开连接的屏障,接受客户连接,并接收用户对社区(fd)的连接。
5. 通信
- 接收数据
- 发送数据
六,对话结束了,解开装置
tcp 客户通信程序:
一. 创建通信套接字(fd)
二. 连接服务器,它需要一个 IP 地址和一个端口号来表示您想要连接到的服务器 。
三. 如果连接成功,客户可以直接交谈并接受服务。
- 接收数据
- 发送数据
4. 断开连接
tcp 服务器服务器-服务器通信过程 :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main()
{
/ 1. 创建监听套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
perror("socket");
exit(0);
}
// 2.绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET; //ipv4
我不知道你在说什么,Adr. 我不知道你在说什么,sin_addr.s_addr = InDID_ANY;//IP进入内核
// 上面的代码等价于:inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
我不知道你指的是什么,Ardr.sin_port = htons(8989);//port
int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if (ret == -1)
{
perror("bind");
exit(0);
}
// 3.设置监听
int lis_ret = listen(fd, 100);
if (lis_ret == -1)
{
perror("listen");
exit(0);
}
/4. 等待连接
struct sockaddr_in addr_cli;
int len = sizeof(addr_cli);
int connfd = accept(fd, (struct sockaddr*)&addr_cli, &len);
if (connfd == -1)
{
perror("accept");
exit(0);
}
// 通讯
while (1)
{
// 读数据
char recvBuf[1024];
read(connfd, recvBuf, sizeof(recvBuf));
printf("recv buf : %sn", recvBuf);
// 写数据
write(connfd, recvBuf, strlen(recvBuf));
}
//释放
close(fd);
close(connfd);
return 0;
}
tcp 客户阴蒂通讯程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main()
{
/ 1. 创建通信套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
perror("socket");
exit(0);
}
//2. 与服务器的链接
struct sockaddr_in addr;
addr.sin_family = AF_INET; // ipv4
我不知道你是什么意思, Ardr.sin_port = htons (8989); / 服务器听众端口, 字节顺序应该是网络字节顺序
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
if(ret == -1)
{
perror("connect");
exit(0);
}
int i = 0;
// 通信
while(1)
{
// 读数据
char recvBuf[1024];
// 写数据
sprintf(recvBuf, "data: %dn", i++);
write(fd, recvBuf, strlen(recvBuf));
/ 如果客户端不提供数据,则使用默认区块。
read(fd, recvBuf, sizeof(recvBuf));
printf("recv buf: %sn", recvBuf);
sleep(1);
}
// 释放资源
close(fd);
return 0;
}
本文由 在线网速测试 整理编辑,转载请注明出处。