socket套接字

article/2025/10/20 21:10:19

在这里插入图片描述

欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起探讨和分享Linux C/C++/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。


socket套接字

    • 1. 什么是socket套接字
    • 2. socket编程
    • 3. 网络字节序
    • 4. IP地址转换函数
    • 5. sockaddr数据结构
    • 6. 网络套接字函数
    • 7. TCP通信流程图


专栏:《网络编程》《Linux从小白到大神》


1. 什么是socket套接字

套接字就像一个插座,插座需要一个插头来连接双方才能通电,而socket通信也需要两个端,一个服务端一个客户端。一般来说,服务端是被动的,客户端是主动的,也就是说服务端应该先启动,启动之后就被动的去准备被(客户端)连接以提供服务,而客户端需要服务的时候就主动去连接服务器端。

实际上,socket编程就是网络IO编程,同样也是读写操作,只不过是对网络进行读写,通过read/write和文件描述符来完成读写。我们在创建套接字的时候,会得到文件描述符,然后就可以通过这个文件描述符来完成读写操作。

实际上,我们在进程间通信时用的管道也是在内核中分配一块缓冲区,这个缓冲区是用一个环形队列来维护的,本质是内存中的一块存储空间,在管道的读写两端分别对应一个文件描述符,操作读端的文件描述符fd就相当于操作内核缓冲区。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NdD0PWy6-1672383966901)(Typora_picture_reference/1660273767824.png)]

套接字创建成功后,也会得到一个文件描述符fd,通过fd来操作一块内核缓冲区。在服务器端创建一个套接字,就会得到一个内核缓冲区和文件描述符,这个缓冲区分为读写两部分。在客户端发数据使用的是write操作,当我们执行write(fd)的时候,数据并不是直接写到网上的,而是先写到文件描述符对应的内核缓冲区中的写缓冲区部分,写缓冲区中只要有数据就会自动发送到服务器端的读缓冲区中,服务器端通过read就可以把数据读出。我们所做的只有read和write操作,其他操作都是由操作系统完成的。需要注意的一点是,读缓冲区中的数据读走了之后就没有了,和管道一样。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aAxUpTMS-1672383966902)(Typora_picture_reference/1660274216613.png)]

套接字对应的文件描述符默认也是阻塞的,实际上阻塞是文件描述符对应的文件所拥有的性质,而不是read/write的属性,这两个函数只负责读取或者写数据,即阻塞性质是对文件描述符所对应的文件类型而言的。

2. socket编程

  • socket是一套网络通信的函数接口
  • socket内封装了传输层协议
    • TCP
    • UDP

socket编程就是使用别人提供的一套网络通信接口进行编程。比如说我们使用浏览器搜索内容,浏览器使用的是HTTP协议,而HTTP协议再往下封装的就是TCP协议。

在套接字编程时需要IP和Port:

  • IP地址:在网络环境中,需要IP来定位一台主机

  • 端口号Port:在一台主机上,需要Port来定位一个进程

  • IP:Port

3. 网络字节序

  • 大端:网络字节序,数据的高位字节存储在内存的低地址。
  • 小端:主机字节序,数据的高位字节存储在内存的高位地址。常见的主机数据都是小端存储。

函数介绍:

#include <arpa/inet.h>

(1) 主机字节序转网络字节序

uint16_t htons(uint16_t hostshort); //端口
uint32_t htonl(uint32_t hostlong); //IP

(2) 网络字节序转主机字节序

uint16_t ntohs(uint16_t netshort); //端口
uint32_t ntohl(uint32_t netlong); //IP

假如说我们要将小端字节序转换为大端字节序,如果主机是小端字节序,这些函数将参数做相应的大小端转换后返回,如果主机是大端字节序,这些函数将不做任何变换,将参数原封不动的返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nRLDsHML-1672383966902)(Typora_picture_reference/1660305362431.png)]

常见的文件字节序:

  • Adobe PS — Big Endian
  • BMP — Little Endian
  • GIF — Little Endian
  • JPEG — Big Endian
  • MacPaint — Big Endian
  • RTF — Little Endian

注:在Java以及所有的网络通讯协议都是使用Big-Endian编码。

4. IP地址转换函数

指定IP转换为点分十进制字符串

  • 本地IP转网络字节序:字符串 —> int(大端方式存储)

    int inet_pton(int af, const char* src, void* dst);
    
    • af:地址簇协议
    • src:点分十进制IP
    • dest:传出参数,转换后的int整形的存放地址
  • 网络字节序转本地IP:int —> 字符串

    const char *inet_ntop(int af, const void* src, char* dst, socklen_t size);
    

5. sockaddr数据结构

  • sockaddr
  • sockaddrin
  • sockaddrun
struct sockaddr {	/* address family, AF_xxx */sa_family_t sa_family; /* 14 bytes of protocol address */char sa_data[14];			
};
struct sockaddr_in {__kernel_sa_family_t sin_family;   // 地址族协议 		__be16 sin_port;	// 端口struct in_addr sin_addr;   // IP地址				unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)];
};
struct in_addr {__be32 s_addr;
};

IPv4地址用socketaddr_in结构体表示,包括16位端口号和32位IP地址,IPv6地址用socketaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。

6. 网络套接字函数

(1) 创建套接字

int socket(int domain, int type, int protocol);
  • 创建一个套接字
  • domin
    • AF_INET:这是大多数用来产生socket的协议,使用TCP或UDP来传输,使用IPv4的地址;
    • AF_INET6:使用IPv6的地址;
    • AF_UNIX:本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器端都在同一台机器上的时候使用;
  • type
    • SOCK_STREAM:流式协议,这个协议是按照顺序的、可靠的、数据类型完整的、基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输的;
    • SOCK_DGRAM:报式协议,这个协议式无连接的、固定长度的传输调用,该协议是不可靠的,使用UDP进行传输;
    • SOCK_SEQPACKET:该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输,必须把这个包完整的接收才能进行读取;
    • SOCK_RAW:socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议,ping以及traceroute都使用该协议;
    • SOCK_RDM:这个类型使用较少,在大部分操作系统上没有实现,它提供给数据链路层使用,不保证数据包的顺序;
  • protocol:设置0表示使用默认协议; 协议,常见的协议有IPPROTO_TCP、IPPTOTO_UDP、 IPPROTO_SCTP、IPPROTO_TIPC他们分别对应这TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。当protocol为0时,会自动选择type类型对应的默认协议;
  • 返回值为文件描述符(套接字),即创建好的socket套接字的文件描述符。On success, a file descriptor for the new socket is returned. On error, -1 is returned, and errno is set appropriately.

(2) 绑定

int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
  • 将本地的IP和端口号与创建出来的套接字绑定,将参数sockfd和addr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。
  • sockfd:创建出的文件描述符
  • addr:端口和IP
  • addrlen:addr结构体的长度,sizeof(addr)

(3) 监听

int listen(int sockfd, int backlog);
  • 设置同时连接到服务器的客户端的个数,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于连接等待状态,如果接收到更多的连接请求就忽略。
  • sockfd:socket函数创建出来的文件描述符;
  • backlog:同时能连接的最大数量,最大值为128;

(4) 接受连接

int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
  • 阻塞等待客户端连接请求,并接受连接。
  • sockfd:文件描述符,使用socket创建出来的文件描述符;
    • 监听的文件描述符;
  • addr:存储客户端的端口和IP,是一个传出参数;
  • addrlen:传入传出参数(值 - 结果),传入sizeof(addr)的大小,函数返回时返回真正接收到地址结构体的大小;
  • 函数返回值是一个套接字,对应客户端,服务器端与客户端进程通信使用accept的返回值对应的套接字。

(5) 连接

int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
  • 客户端需要调用connect()函数连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址。
  • sockfd:套接字;
  • addr:传入参数,指定服务器端地址信息,服务器端的IP和端口;
  • addrlen:第二个参数addr的长度;

7. TCP通信流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CMangJmQ-1672383966903)(Typora_picture_reference/1660475738627.png)]


在这里插入图片描述
在这里插入图片描述



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

相关文章

java 套接字是什么_套接字是什么,套接字通信及其原理

为通信的端点,每个套接字由一个 IP 地址和一个端口号组成。通过网络通信的每对进程需要使用一对套接字,即每个进程各有一个。 通常,套接字采用客户机-服务器架构。服务器通过监听指定端口,来等待客户请求。服务器在收到请求后,接受来自客户套接字的连接,从而完成连接。 实…

网络编程——原始套接字实现原理

目录 1. 基础知识 1.1、概述 1.2、链路层原始套接字 1.3、网络层原始套接字 2、原始套接字的实现 2.1 原始套接字报文收发流程 2.2链路层原始套接字的实现 2.2.1 套接字创建 2.2.2 报文接收 2.2.3 报文发送 2.2.4 其它 2.3 网络层原始套接字的实现 2.3.1 套接字…

UDP套接字编程

参考&#xff1a;《UNIX 网络编程 卷1 : 套接字联网API》 UDP 与 TCP 之间传输存在差异&#xff0c;也导致编写应用程序存在很多差异。UDP 客户端和服务器不建立连接&#xff0c;而是直接使用 sendto 函数给服务器发送数据报。但必须指定目的地的地址作为参数。服务器也不用接…

网络套接字编程

网络套接字编程 一、 认识UDP协议 UDP(User Datagram Protocol 用户数据报协议&#xff0c;是不可靠的数据报传输协议&#xff0c;不确保数据安全有序的到达对端。 特点&#xff1a; 传输层协议无连接不可靠传输面向数据报 应用场景&#xff1a;性能要求大于安全要求&…

彻底弄懂套接字

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;网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能…