网络套接字编程

article/2025/10/20 21:12:40

网络套接字编程

一、 认识UDP协议

UDP(User Datagram Protocol 用户数据报协议,是不可靠的数据报传输协议,不确保数据安全有序的到达对端。

特点:

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

应用场景:性能要求大于安全要求,比如视频传输。

二、UDP通信程序的编写

0. 前提

a. 什么是套接字编程

就是网络通信程序的编写,网络中的各种通信,都是用户与服务器之间的通信,不存在用户与用户之间的直接通信。也不存在服务器和服务器之间的直接通信。

b. 网络通信都是两端主机之间的通信:客户端,服务端。

客户端:网络通信中用户的一端,是进行业务请求的一端,是主动发起请求的一端。

服务端:网络通信中提供服务的一端,针对客户端请求进行处理的一端,是被动接收请求的一端。

客户端要给服务端发送数据,客户端怎么知道要发送给谁呢?

  • 服务端都会提前将自己的地址信息封装在客户端中,也正是因为如此,客户端的地址信息通常都不能改变。

c. 网络传输的数据都会具有五元组

  • sip:源端IP
  • sport:源端端口
  • dip:对端IP
  • dport:对端端口
  • protocol:协议

五元组标识了一条通信:数据从哪来,到哪去,用的什么协议。

1. 了解通信流程

a. 客户端

  1. 创建套接字:在内核中创建了一个套接字结构(struct socket),用于关联网卡与当前通信进程。
  2. 绑定地址信息:不建议进行,因为一旦绑定了地址,发送数据的源端地址就是固定的,但是一个端口只能被一个进程占用,容易冲突。
  3. 发送数据:将数据放到发送缓冲区,并告诉套接字这些数据要发送给谁(对端地址),系统在封装的时候就会发现数据没有源端地址,这时操作系统就会自动选择一个合适的地址信息进行绑定。
  4. 接收数据:从套接字的接收缓冲区取出数据。
  5. 关闭套接字:释放资源。

b. 服务端

  1. 创建套接字:在内核中创建了一个套接字结构(struct socket),用于关联网卡与当前通信进程。
  2. 为套接字绑定地址信息:描述sip和sport到socket中,用于告诉操作系统当收到数据时,这个数据要发送给所描述的sip和sport的时候,要交给这个socket进行处理。
  3. 接收数据:从套接字的接收缓冲区中取出数据,顺便获取这个数据是谁发的(源端地址)。
  4. 发送数据:将要发送的数据放入到发送缓冲区中,并且告诉套接字这个数据要发送给谁。
  5. 关闭套接字:释放资源。

2. 认识通信接口

  1. 创建套接字

    int socket(int domain, int type, int protocol);

    domain:地址域类型,用于决定通信使用什么地址结构,IPV4地址域类型则是AF_INET。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1jl2eIjl-1643444904654)(C:\Users\han\AppData\Roaming\Typora\typora-user-images\image-20220121214410814.png)]

    type:套接字类型,决定使用什么套接字传输方式。

    • SOCK_STREAM:流式套接字,基于连接的,有序的,可靠的字节流传输服务。

    • SOCK_DGRAM:数据报套接字,无连接的,不可靠的数据报传输服务。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5sd5dI53-1643444904655)(C:\Users\han\AppData\Roaming\Typora\typora-user-images\image-20220121214751938.png)]

    protocol:使用的协议类型,流式套接字默认0则表示TCP协议,数据报套接字默认0则表示UDP协议。

    返回值:套接字操作句柄(文件描述符),失败返回-1。

  2. 绑定地址信息

    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    sockfd:创建套接字返回的操作句柄,用于决定给哪个套接字绑定地址。

    addr:绑定地址的信息。

    len:地址信息长度。

    **注意:**struct sockaddr是一个通用的地址接口,在真正使用的时候并不会使用它,而是使用一个具体的通信地址结构,然后强转其类型并传入数据即可,bind接口内部会根据传入数据的前2个字节决定这个传入的地址数据该如何解析。len是地址信息长度,作用是第二个参数传入的是地址,所以要指定访问的长度,防止访问越界。

    返回值:成功返回0,失败返回-1.

  3. 发送数据

    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

    sockfd:创建套接字返回的操作句柄。

    buf:要发送的数据的首地址(socket并不关心发送数据的具体内容)。

    len:要发送的数据长度。

    flags:标志位,0是默认阻塞操作。

    dest_addr:目的端地址信息。

    addrlen:地址信息长度。

    返回值:成功返回实际发送的数据长度,失败返回-1。

  4. 接收数据

    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

    sockfd:创建套接字返回的操作句柄。

    buf:一块缓冲区的首地址,用于存放获取的数据。

    len:想要发送的数据长度。

    flags:标志位,0是默认阻塞操作。(若缓冲区没有数据则会等待)

    src_addr:接收到的数据的源端地址信息。

    *addrlen:输入输出参数,用于指定要获取的地址长度,以及返回实际长度。

    返回值:成功返回获取到的数据长度,失败返回-1。

  5. 关闭套接字

    int close(int fd);

  6. 字节序转换接口

    网络通信需要使用网络字节序,因此要考虑网络字节序转换问题

    16位数据的主机与网络字节序转换:uint16_t htons(uint16_t hostshort); uint16_t ntohs(uint16_t netshort);

    32位数据的主机与网络字节序转换:uint32_t htonl(uint32_t hostlong); uint32_t ntohl(uint32_t netlong);

    将一个点分十进制的字符串IP地址转换为网络字节序整数IP地址:in_addr_t inet_addr(const char *cp);

    将一个网络字节序整数IP地址转换为点分十进制的字符串IP地址:char *inet_ntoa(struct in_addr in);

3. 编写程序

服务器端:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>int main(int argc, char* argv[])
{//从参数中获取服务端要绑定的地址:包括IP地址和端口号 if(argc < 3){printf("参数不全\n");return -1;}char* src_ip = argv[1];//获取要绑定的IP地址int srv_port = atoi(argv[2]);//获取要绑定的端口//1.创建套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET表示IPV4地址域类型;SOCK_DGRAM表示数据报套接字,0默认是使用UDP协议if(sockfd < 0){perror("socket error");return -1;}//2.绑定地址信息struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(srv_port);addr.sin_addr.s_addr = inet_addr(src_ip);socklen_t len = sizeof(addr);int ret = bind(sockfd, (struct sockaddr*)&addr, len);if(ret < 0){perror("bind error");return -1;}//3.接收数据while(1){char tmp[4096] = {0};struct sockaddr_in client_addr;//获取发送端的地址信息len = sizeof(client_addr);ret = recvfrom(sockfd, tmp, 4095, 0, (struct sockaddr*)&client_addr, &len);if(ret < 0){perror("recvfrom error");return -1;}printf("%s:%d - %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), tmp);//4.发送数据printf("server input:");fflush(stdout);memset(tmp, 0x00,4096);//清空缓冲区内容scanf("%s",tmp);ret = sendto(sockfd, tmp, strlen(tmp), 0, (struct sockaddr*)&client_addr, len);}//5.关闭套接字close(sockfd);return 0;
}

客户端:

#include <cstdio>
#include <unistd.h>
#include <iostream>
#include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
using namespace std;class UdpSocket
{private:int _sockfd;public:UdpSocket():_sockfd(-1){}public://创建套接字bool Socket(){_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if(_sockfd < 0){perror("socket error");return  false; }return true;}//绑定地址信息bool Bind(const string &ip, int port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);if(bind(_sockfd, (struct sockaddr*)&addr, len) < 0){perror("bind error");return false;}return true;}//发送数据bool Send(const string &data, const string &ip, int port){struct sockaddr_in peeraddr;peeraddr.sin_family = AF_INET;peeraddr.sin_port = htons(port);peeraddr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret = sendto(_sockfd, &data[0], data.size(), 0, (struct sockaddr*)&peeraddr, len);if(ret < 0){perror("send error");return false;}return true;}//客户端实际上是不需要接收服务器的地址的,因为他本来就知道bool Recv(string *buf, string *ip = nullptr, int* port = nullptr){struct sockaddr_in peeraddr;socklen_t len = sizeof(sockaddr_in);char tmp[4096] = {0};int ret = recvfrom(_sockfd, tmp, 4095, 0, (struct sockaddr*)&peeraddr, &len);if(ret < 0){perror("recvfrom error");return false;}buf->assign(tmp,ret);//从tmp字符串位置开始截取ret长度的数据到buf中if(ip != nullptr){*ip = inet_ntoa(peeraddr.sin_addr);}if(port != nullptr){*port = ntohs(peeraddr.sin_port);}return true;}//关闭套接字bool Close(){return close(_sockfd);}
};#include"udpsocket.hpp"
#include <cstdlib>
using namespace std;
int main(int argc, char* argv[])
{//通过运行参数获取服务端的地址信息if(argc < 3){cout<<"参数不全"<<endl;return -1;}string srv_ip = argv[1];int srv_port = atoi(argv[2]);//1.创建套接字UdpSocket sock;sock.Socket();//2.绑定地址信息(不推荐)while(1){string buf;cout << "请输入要发送的内容";cin >> buf;//3.发送请求sock.Send(buf, srv_ip, srv_port);//4.接收相应buf.clear();sock.Recv(&buf);cout << buf << endl;}//5.关闭套接字sock.Close();return 0;
}

三、认识TCP协议

TCP(Transmission Control Protocol 传输控制协议),是面向连接的,可靠的字节流传输协议(确保了数据安全有序的到达对端,并且建立连接后才可以进行通信),TCP协议为了保证可靠传输,因此使用了很多的机制来完成,因此传输性能相对于UDP协议来说较低。

特点

  • 传输层协议
  • 基于连接的
  • 可靠传输
  • 面向字节流

应用场景:安全需求大于性能需求,比如文件传输。

四、TCP通信程序的编写

1.了解通信流程

a.客户端

  1. 创建套接字:关联网卡与进程。
  2. 绑定地址信息:不推荐主动绑定。
  3. 向服务端发起连接请求:如果没有主动绑定地址则会自动选择合适的地址进行绑定。连接一旦建立成功,客户端的socket中也会具有完整的五元组信息。
  4. 收发数据。
  5. 关闭套接字。

b.服务端

  1. 创建套接字:创建套接字:在内核中创建了一个套接字结构(struct socket),用于关联网卡与当前通信进程。
  2. 绑定地址信息:为套接字绑定地址信息:描述sip和sport到socket中,用于告诉操作系统当收到数据时,这个数据要发送给所描述的sip和sport的时候,要交给这个socket进行处理。
  3. 开始监听:使socket进入listen状态,开始处理客户端连接请求。服务端会为每个新的客户端的连接请求创建一个新的socket,在内部描述完整的五元组信息,这个新建的套接字只与固定的客户端进行通信。
  4. 获取新建套接字的操作句柄:往后与指定的客户端进行通信都是通过新建的套接字(被称为连接套接字)完成的,原本的套接字(被称为监听套接字)只用来新建连接请求。
  5. 收发数据。
  6. 关闭套接字。

2. 通信接口认识

  1. 服务端开始监听

    int listen(int sockfd, int backlog);

    sockfd:套接字描述符。

    backlog:当前服务器在同一时间所能处理的最大的客户端连接请求数量(同一时刻的最大并发连接数)。

    SYN泛洪攻击:恶意主机伪造IP地址,向服务器发送大量的连接请求,这样服务端就会不断创建新的连接套接字,如果服务端对新建套接字的数量不做限制的话,有可能瞬间资源耗尽,系统崩溃。这个限制就是backlog,有了这个限制,遇到SYN泛洪攻击的时候,顶多是无法处理正常的请求,但是不会让系统崩溃,之前的连接还可以正常通信。

    返回值:成功返回0,失败返回-1。

  2. 客户端发送连接请求

    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    sockfd:套接字描述符。

    addr:服务端的地址信息,IPV4通信使用struct sockaddr_in的结构。

    len:地址信息长度。

    返回值:成功返回0,失败返回-1。

  3. 服务端获取新建连接句柄

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

    sockfd:监听套接字描述符(监听套接字描述符仅用来进行新建连接和监听)。

    addr:获取要进行连接的客户端地址信息,描述的是当前要获取的这个套接字是与哪个客户端进行通信的。

    len:输入输出型参数:指定要获取的地址长度,以及返回实际获取的地址长度。

    返回值:成功返回新建连接的套接字描述符,用于后续与客户端进行通信;失败返回-1。

  4. 发送数据:

    ssize_t send(int sockfd, const void *buf, size_t len, int flags);

    sockfd:套接字描述符,对于服务端来说,一定是accept获取到的新建连接的套接字描述符。

    buf:要发送的数据首地址。

    len:要发送的数据首地址。

    flag:标志位,通常置0,表示阻塞发送,就是把数据放到发送缓冲区,系统进行封装发送,如果缓冲区满了则进行等待。

    返回值:成功返回实际发送的数据的长度;失败返回-1。

  5. 接收数据

    ssize_t recv(int sockfd, void *buf, size_t len, int flags);

    sockfd:监听套接字描述符。

    buf:一个缓冲区空间首地址,用于存放接收的数据。

    len:想要获取的数据长度,不能大于buf的缓冲区长度。

    flag:标志位,通常置0,表示阻塞接收,就是socket接收缓冲区中如果没有数据则阻塞。

    返回值:成功返回实际获取到的数据长度;失败返回-1;连接断开返回0。

  6. 关闭套接字

    int close(int fd);

    部分关闭连接

    int shutdown(int sockfd, int how); 这个操作并不会完全释放资源。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RSKNwn6E-1643444904656)(C:\Users\han\AppData\Roaming\Typora\typora-user-images\image-20220128150431045.png)]

    shutdown更多用于进行半关闭连接,让对方知道自己不再发送数据或者不再接收数据了,但是要注意shutdown不是用于关闭套接字释放资源的,就算调用了shutdown,最后也必须使用close关闭释放资源。

3. 程序编写

封装TCPSocket类

#include <iostream>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAX_LISTEN 5
using namespace std;class TCPSocket
{private:int _sockfd;public:TCPSocket():_sockfd(-1){}//创建套接字bool Socket(){_sockfd = socket(AF_INET, SOCK_STREAM, 0);if(_sockfd < 0){perror("socket error");return false;}return true;}//绑定地址信息bool Bind(const string &ip, int port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(addr);if(bind(_sockfd, (struct sockaddr*)&addr, len) < 0){perror("bind error");return false;}return true;}//服务端开始监听bool Listen(int backlog = MAX_LISTEN){if(listen(_sockfd, backlog) < 0){perror("listen error");return false;}return true;}//向服务端发起连接请求bool Connect(const string &srv_ip, int srv_port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(srv_port);addr.sin_addr.s_addr = inet_addr(srv_ip.c_str());socklen_t len = sizeof(addr);if(connect(_sockfd, (struct sockaddr*)&addr, len) < 0){perror("connect error");return false;}return true;}//获取新建连接bool Accept(TCPSocket* new_sock, string* cli_ip, int* cli_port){struct sockaddr_in addr;socklen_t len = sizeof(addr);int new_fd = accept(_sockfd, (struct sockaddr*)&addr, &len);if(new_fd < 0){perror("accept error");return false;}new_sock->_sockfd = new_fd;if(cli_ip != nullptr){*cli_ip = inet_ntoa(addr.sin_addr);}if(cli_port != nullptr){*cli_port = ntohs(addr.sin_port);}return true;}bool Send(const string &data){ssize_t ret = send(_sockfd, data.c_str(), data.size(), 0);if(ret < 0){perror("send error");return false;}return true;}bool Recv(string *buf){char tmp[4096] = {0};ssize_t ret = recv(_sockfd, tmp, 4096, 0);if(ret < 0){perror("recv error");return false;}else if(ret == 0){cout<<"连接断开"<<endl;}buf->assign(tmp,ret);return true;}bool Close(){if(_sockfd > 0){close(_sockfd);_sockfd = -1;}return true;}
};

客户端

#include "TCPSocket.hpp"int main(int argc, char* argv[])
{if(argc < 3){cout<<"参数不全"<<endl;return -1;}string srv_ip = argv[1];int srv_port = stoi(argv[2]);TCPSocket sock;//1.创建套接字sock.Socket();//2.向服务端发起连接请求sock.Connect(srv_ip, srv_port);//3、循环收发数据while(1){string data;cout<<"clint input:";fflush(stdout);cin>>data;sock.Send(data);data.clear();sock.Recv(&data);cout<<"server response"<<data<<endl;}//4.关闭套接字sock.Close();return 0;
}

服务端

#include "TCPSocket.hpp"
#include <unordered_map>unordered_map<string, string> table = 
{{"hello", "你好"},{"goodmorning", "早上好"}
};int main()
{TCPSocket listen_sock;//1.创建套接字listen_sock.Socket();//2.绑定地址信息listen_sock.Bind("0.0.0.0", 9000);//3.开始监听listen_sock.Listen();//5.使用新建连接收发数据while(1){//4.获取新建连接TCPSocket new_sock;string cli_ip;int cli_port;listen_sock.Accept(&new_sock, &cli_ip, &cli_port);cout<<"new connect"<<cli_ip<<":"<<cli_port<<endl;string buf;new_sock.Recv(&buf);string rsp;auto it = table.find(buf);if(it == table.end()){rsp = "未知请求";}rsp = it->second;new_sock.Send(rsp);}//6.关闭套接字listen_sock.Close();return 0;
}

http://chatgpt.dhexx.cn/article/ubB8XD6Z.shtml

相关文章

彻底弄懂套接字

1.什么是套接字&#xff08;英文名&#xff1a;插座&#xff09; 套接字&#xff08;socket&#xff09;是一种通信机制&#xff0c;凭借这种机制&#xff0c;客户/服务器系统的开发工作既可以在本地单机上进行&#xff0c;也可以跨网络进行。Linux所提供的功能&#xff08;如打…

什么是套接字?Socket基本介绍

什么是套接字&#xff1f;Socket基本介绍 一、什么是套接字&#xff1f;二、套接字特性三、套接字缓冲区 一、什么是套接字&#xff1f; 套接字是一种通信机制&#xff08;通信的两方的一种约定&#xff09;&#xff0c;socket屏蔽了各个协议的通信细节&#xff0c;提供了tcp/…

微信小程序-引入地图、获得经纬度

实际这是一个获得经纬度的方法&#xff0c;但是有了经纬度可以做很多事情 点击按钮跳转到一个单独的页面&#xff08;地图&#xff0c;可导航&#xff09;在页面内嵌一个独立的小区域 首先可看一下腾讯地图官方文档 微信小程序JavaScript SDK | 腾讯位置服务 最基本&#xf…

微信小程序-批量地图标记

效果图 wxml <loading hidden"{{!loading}}">加载中</loading><view class"mapBox"><map id"myMap" scale"12" longitude"{{longitude}}" latitude"{{latitude}}" markers"{{mark…

实现地图功能 利用微信内置的微信地图

效果图&#xff1a; 查看微信开发文档&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.chooseLocation.html 其实不难&#xff0c;查看官方文档&#xff0c;一目了然 直接上代码&#xff1a; map.wxml: <button bindtap"mapViewTap&…

微信小程序应用百度地图API

微信小程序&#xff0c;定位地点&#xff0c;应用bdmap API 1 申请 百度地图开放平台页面&#xff1a;控制台&#xff0c;添加应用 应用类型选微信小程序&#xff0c;添加微信小程序名称和APP ID 2. 微信小程序后台设置 进入微信公众平台&#xff0c;开发管理 服务器域名&a…

微信接入js-sdk-获取地理位置,打开微信内置地图

1.第一步当然是已经正确接入了微信并且配置好了回调安全域名。不会的朋友可以看看《微信开发-初级接入微信公众平台MP》 2. 引用微信js-sdk, http://res.wx.qq.com/open/js/jweixin-1.0.0.js&#xff0c;然后通过config接口注入权限验证配置。先在自己的服务器上写个获取数据…

微信地图 leaflet 腾讯地图

本来在微信项目中使用的高德地图&#xff0c;发现不是想象中的好用&#xff0c;而且用了微信&#xff0c;感觉使用腾讯地图会比较方便&#xff0c;所以&#xff0c;索性使用leaflet腾讯地图的底图来实现。 其中关于正确使用腾讯地图参考了https://github.com/wuxiashuangji/TX…

微信地图组件小程序报错“permission“

报错原因 地图可以任意添加&#xff0c;但用户的位置属于个人隐私&#xff0c;因此需要添加服务引导程序&#xff0c;告知用户地理位置的获取。需要添加 Permission &#xff08;小程序权限获取设置&#xff09;。 解决方法 该片段用于获取位置权限&#xff0c;注意该片段如…

uniapp 微信对接地图的三种操作

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 1.uni.getLocation 获取当前经维度 先上代码 let that this// 获取用户是否开启 授权获取当前的地理位置、速度的权限。uni.getSetting({success (res) {console.log(res)// 如果没有授权if (!res.au…

微信地图多边形算法及判断点位是否在多边形中

最新一个小项目,需要用到地图定义自由区域,并判断选点是否落在此区域内,思路是通过map的polygons中的points来定义多边形边界,通过polygons的fillColor 、 strokeColor、strokeWidth来进行选区颜色的渲染。 然后再通过地图中心点位的移动来确定需要判断的选点(因为小程序地…

【微信小程序】打开微信内置的地图

前言 略 打开微信内置的地图 wx.openLocation({latitude: 38.043622, /*纬度&#xff0c;使用 gcj02 国测局坐标系*/longitude: 114.514746, /*经度&#xff0c;使用 gcj02 国测局坐标系*/scale: 18, /*缩放比例&#xff0c;范围5~18*/name: 石家庄市长安公园人民广场, /*这…

小程序 – 调用微信地图功能小记 + 滑动事件

学习文献官方API对 location 地图 API的具体分析日历插件 - github 2-有回调事件小程序滚动问题小程序上下滑动事件小程序map地图上显示多个marker wx.getLocation(Object object) -获取当前的地理位置、速度。并且能打印出地址消息&#xff1b; wx.openLocation() – 是使用…

微信地图wgs84坐标,gcj02坐标,bd09坐标转换

微信小程序三种常见经纬度坐标系的转化 遇见问题&#xff1a;在其它端点位显示正常&#xff0c;在小程序上点位发生偏移&#xff0c;微信小程序是gcj02坐标&#xff0c;就是xxToGcj02&#xff0c;具体情况具体分析 我们常用的地图api坐标系有wgs84坐标系&#xff0c;gcj02坐标…

Android仿微信地图定位和位置选择(上)

一、地图集成 集成腾讯地图SDK&#xff0c;https://lbs.qq.com/&#xff0c;申请AppKey。 1、dependencies implementation com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.2.6 implementation com.tencent.map:tencent-map-vector-sdk:4.3.4 2、AndroidMa…

微信公众号h5界面获取展示微信内置地图与地图坐标间的转换 — 微信地图(gcj02)转为百度地图

此文章中实例用测试号进行演示 。getLocation openLocation 主要运用微信JS-SDK&#xff0c;微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK&#xff0c;网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能…

微信小程序地图功能

一&#xff0c;显示地图 <map id"map" longitude"{{longitude}}" latitude"{{latitude}}" scale"14" controls"{{controls}}" bindcontroltap"controltap" markers"{{markers}}" bindmarkertap"…

微信小程序---高德地图API

本文章介绍微信小程序调用高德地图API的过程&#xff0c;使用高德定位功能做演示。微信小程序目前支持百度地图、高德地图、腾讯地图。用法可以说是基本完全一样&#xff0c;本文章以高德为例&#xff0c;简单说一下他们的区别&#xff0c;高德地图精度应该是最准确的&#xff…

微信小程序地图控件Map的使用

本文介绍微信小程序map控件的使用 map为原生控件之一…… 介绍完map控件之后下面直接来看代码怎么实现吧 和往常一样&#xff0c;这些代码贴过去就可以直接通用的 首先wxml文件(极简)&#xff1a; <map id"map" scale"16" controls"{{controls}}&…

微信小程序地图导航实例讲解

微信小程序地图导航实例讲解 先上演示视频准备工作如下在app.json中添加 watch页面代码watch.wxmlwatch.wxsswatch.js connect导航页面使用在腾讯位置服务需要获取key地图选点当用户未点击选址时&#xff0c;默认传入用户当前地址&#xff0c;可以在onShow方法中定义 代码解读 …