登录发现更多内容
首页
分类
发帖
账号
自动登录
找回密码
密码
登录
立即注册
立即登录
立即注册
其他登录
QQ
微信
首页
Portal
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
产品教程
BBS
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
开发资料
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
样品购买
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
IoT云平台
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
GitHub
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
技术博客
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
搜索
搜索
热搜:
LoRa
ESP8266
安信可
本版
帖子
用户
请
登录
后使用快捷导航
没有账号?
立即注册
每日签到
任务
广播
导读
排行榜
设置
我的收藏
退出
6
0
0
首页
技术杂谈
›
socket编程(一) - 基本介绍
返回列表
socket编程(一) - 基本介绍
[ 复制链接 ]
发布帖子
可乐klelee
金牌会员
9
主题
24
回帖
1473
积分
金牌会员
金牌会员, 积分 1473, 距离下一级还需 1527 积分
金牌会员, 积分 1473, 距离下一级还需 1527 积分
积分
1473
私信
6人留言
楼主
技术杂谈
1153
6
2023-9-4 21:28:32
每学习一个新的知识的时候,我们都会问这是什么?socket是什么?在各大搜索引擎搜索socket都会从插座给你介绍socket的起源。这些,都不重要!对我们来说,我们只需要知道socket就是可以**用于网络设备互相通信的一个工具**就可以,我们通常称socket为套接字,知道这些就够了。 ## 写在前面 由于Linux有“一切皆文件”的特性,在socket编程这一块,Linux和Windows的实现是有所出入的,本系列文章默认以Linux为环境。实际上在嵌入式以及物联网领域,更多的还是以Linux为基础的。 socket系列文章大概会分为三篇: 1. 基本介绍socket,了解什么是socket,了解socket的基本原理,了解都有哪些类型的socket。顺便会简单介绍IP、MAC和端口,最后写一个简单的socket demo。 2. 接着上一节的socket demo中,深入分析socket常用的数据结构,接口函数等基础的语法知识。最后通过了解我最近在做的项目中对socket的使用,来更深入的了解socket的应用。 3. socket的高级应用,包括文件传输,域名访问等等。最后会说一说socket中使用udp协议的一些内容。 ## 基本原理 那么,从这里开始,我们正式的开始学习socket。 废话部分:这里我斟酌了很久,甚至写了删,删了再写,如此反复,我就在想,该如何简单的介绍socket通信的原理,让我自己明白,也能让看到这个文章的每一位朋友明白?我还是决定,从socket的分类说起。 ### socket的分类 由于底层实现的不同,其实socket的实现也是千差万别的。本片文章中主要说说,流式套接字和数据报式套接字吧。可以先说明结论: - 流式套接字(SOCK_STREAM):基于`TCP`协议实现,熟悉TCP协议的朋友都知道三次握手,这样做的目的是为了数据安全,同时也确保了数据的完整性。但是,这同时也带来了很明显的缺点,那就是慢。**以上是流式套接字的特点,而针对流式套接字具体的传输方式,我想再具体说明,所谓流式套接字,就是数据在设备之间有顺序的传输,即“ABCDEFGHIJKLMN”, 必须是按照顺序传输的,不可能先收到B然后再收到A。这样做也是确保数据完整性和安全性的一种实现。** - 数据报式套接字(SOCK_DGRAM):基于`UDP`协议实现,UDP协议可能在编程的过程中使用频率没有TCP协议那么高,UDP最明显的特点就是不需要进行三次握手,只管发送数据,至于客户端能否收到数据,我不管,数据完全与否我也不管。 在本次socket的学习中,主要以基于TCP协议的流式套接字,数据报,后面也会简单的涉及。 ### 流式套接字收发流程 socket通信是CS架构的,服务端和客户端都需要做相应的配置,才能建立通信。在正式开始之前,我希望我们能先大概了解IP,MAC和Port之间的区别: - IP : 确定你的大体位置,也就是局域网所在位置 - MAC: 确定你的设备是局域网中的哪台设备 - Port: 确定需要连接的进程是设备中的哪一个 首先来看**服务端**: 1. 首先申请一个socket。 在这里插一嘴,在Linux环境中,贯彻了一切皆文件的思想,所以这里的socket实际上也是一个文件,所以申请一个socket,相当于调用open()函数,生成了一个文件描述符,而接下来的所有操作,在底层逻辑上看来就是对文件的各种IO操作。 2. 将申请到的socket与IP和Port绑定。 3. 服务端开始监听该socket 4. 服务端阻塞等到客户端连接 同时,另外一台设备,也就是**客户端**: 1. 申请一个socket。 为什么客户端也要申请一个socket?上面我们提到了服务端创建的socket实际上就是一个文件,相关的操作也是对文件的操作,所以客户端新建一个socket,就是对服务端socket的一个承载。 2. 配置要连接的IP和Port 3. 连接 4. 与服务端进行数据交互 5. 交互完成之后关闭套接字 6. 客户端流程结束 回到服务端,其实在实际的应用中,服务端的等到客户连接过程是循环等待的。对于程序而言,服务器端的socket资源在使用完毕之后也需要及时释放。 ## socket demo 最后,我们通过一个特别简单的demo来初次看一下socket的连接过程。 代码段:`socket_demo.c` ```c #include
#include
#include
#include
#include
#include
int server_socket() { int server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 创建socket,返回值实际上就是一个fd struct sockaddr_in server_addr; // 配置服务端IP和端口 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("192.168.1.10"); server_addr.sin_port = htons(6666); bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); // 将socket和IP以及端口绑定 listen(server_socket, 20); // 开始监听 struct sockaddr_in client_addr; socklen_t client_addr_size = sizeof(client_addr); while (1) { // accept函数会阻塞等待客户端的连接,并返回客户端的socket int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_size); char str[] = "Hello Socket!"; send(client_socket, str, sizeof(str), 0); // 发送Hello Socket给客户端 close(client_socket); } close(server_socket); return 0; } int client_socket() { int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("192.168.1.10"); server_addr.sin_port = htons(6666); connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); char buffer[15]; recv(client_socket, buffer, 15, 0); printf("Message form server: %s\n", buffer); close(client_socket); return 0; } ``` 代码段:`common.h` ```c #ifndef _COMMON_H #define _COMMON_H extern int server_socket(); extern int client_socket(); #endif /* _COMMON_H */ ``` 上面的demo中,展现了一个socket最基本的连接过程,虽然是最近本的,但是更多高级的,重要的socket用法,都是从基本方法派生的。下一篇文章将,自己讲讲上面每一个函数的具体含义,同时分享我最近项目中需要使用的socket需求。
点赞
0
收藏
0
淘帖
0
────
0
人觉得很赞
────
回复
使用道具
举报
6 回复
电梯直达
正序浏览
倒序浏览
正序浏览
沙发
夜樱99
回复
使用道具
举报
2023-9-4 22:27:11
学习了!
回复
评论
使用道具
举报
板凳
jkernet
来自手机
回复
使用道具
举报
2023-9-5 07:56:21
好文章点赞
回复
评论
使用道具
举报
地板
爱笑
回复
使用道具
举报
2023-9-5 08:23:12
可乐高产~
回复
评论
使用道具
举报
用心做好保姆工作
5
#
ai_mcu
回复
使用道具
举报
2023-9-5 08:54:20
之前接触过
忘差不多了,再跟着大佬走一遍
回复
评论
使用道具
举报
明天总会更好
6
#
Mr.Tail
回复
使用道具
举报
2023-9-5 08:55:51
好详细
回复
评论
使用道具
举报
7
#
开发板
回复
使用道具
举报
2023-9-7 08:53:26
太强了
回复
评论
使用道具
举报
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
立即登录
手机登录
点评
高级模式
本版积分规则
回帖并转播
回帖后跳转到最后一页
返回
今日推荐
AiPi-PalChatV1_“湾湾小何”提示音测试固件V2.9_UART-MCP
[WB2] 实现自动发现局域网下的设备
热帖排行
ra-01sc-p发射功率大小的使用问题
[AiPi-PalchatV1] [Windows] 克隆仓库和在线烧录遇到的一些小问
AT+MQTTPUBRAW指令所支持的最大数据传输量是多少
AiPi-PalChatV1_UART-MCP_v2.8 UART-MCP 协议配置 问题
Ai-WB2蓝牙怎么连接打印机
AI-WB2-12F电脑蓝牙连接秒断,手机搜索不到
AiPi-PalChatV1_“湾湾小何”提示音测试固件V2.9_UART-MCP
从零搭建 Ai-WB2 开发板的 Linux 开发环境—— 基于 VMware 虚拟
统计信息
会员数: 30475 个
话题数: 44644 篇
首页
分类
我的