判断是否是小端:
bool isLittleEndian()
{
union U
{
int i;
char c;
};
U u;
u.i = 0x12345678;
return u.c == 0x78;
}
2.2 字节序转换函数
#include <arpa/inet.h>
// 将 32位主机字节序数据转换成网络字节序数据
//(h:host, n:net,l:long)
uint32\_t htonl(uint32\_t hostint32);
// 将 16 位主机字节序数据转换成网络字节序数据
uint16\_t htons(uint16\_t hostint16);
// 将 32 位网络字节序数据转换成主机字节序数据
uint32\_t ntohl(uint32\_t netint32);
// 将 16 位网络字节序数据转换成主机字节序数据
uint16\_t ntohs(uint16\_t netint16);
3. sockaddr结构
struct sockaddr很多网络编程API诞生早于IPv4协议,那时候都使用的是sockaddr结构体,为了向前兼容,现在sockaddr退化成了(void *)的作用,传递一个地址给函数,至于这个函数是sockaddr_in还是其他的,由地址族确定,然后函数内部再强制转化为所需的地址类型。
结构图
:
struct sockaddr {
unsigned short sa_family; // 2 bytes address family, AF\_xxx unsiged short
char sa_data[14]; // 14 bytes of protocol address
};
struct sockaddr\_in {
short sin_family; // 2 bytes e.g. AF\_INET, AF\_INET6
unsigned short sin_port; // 2 bytes e.g. htons(3490)
struct in\_addr sin_addr; // 4 bytes see struct in\_addr, below
char sin_zero[8]; // 8 bytes zero this if you want to
};
struct in\_addr {
unsigned long s_addr; // 4 bytes load with inet\_pton()
};
用例
:
4. 认识UDP协议
- Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种
无需建立连接就可以发送封装的 IP 数据包的方法
。 - Internet 的
传输层
有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。 传输层协议
无连接
不可靠传输
面向数据报(SOCK_DGRAM)
UDP的框架图
:
5. socket编程接口
- 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
用例
:
- domain:用于设置网络通信的域,socket根据这个参数选择信息协议的族(一般选择如下两个,但不止如此两个)
AF_INET
IPv4 Internet protocols //用于IPV4AF_INET6
IPv6 Internet protocols //用于IPV6
- type:(只列出最重要的三个):
SOCK_STREAM
Provides sequenced, reliable, two-way, connection-based byte streams. //用于TCPSOCK_DGRAM
Supports datagrams (connectionless, unreliable messages ). //用于UDPSOCK_RAW
Provides raw network protocol access. //RAW类型,用于提供原始网络访问
- protocol:置0即可
- 返回值:
成功:非负的文件描述符
失败:-1
- 绑定端口号 (TCP/UDP, 服务器)
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr\* my_addr, socklen_t addrlen);
用例
:
- sockfd:正在监听端口的套接口文件描述符,通过socket获得
- my_addr:需要绑定的IP和端口
- addrlen:my_addr的结构体的大小
- 返回值:
成功:0
失败:-1
- 发送 (TCP/UDP, 服务器)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void \*buf, size_t len, int flags,
const struct sockaddr \*dest_addr, socklen_t addrlen);
用例
:
- sockfd:正在监听端口的套接口文件描述符,通过socket获得
- buf:发送缓冲区,往往是使用者定义的数组,该数组装有要发送的数据
- len:发送缓冲区的大小,单位是字节
- flags:填0即可
- dest_addr:指向接收数据的主机地址信息的结构体,也就是该参数指定数据要发送到哪个主机哪个进程
- addrlen:表示第五个参数所指向内容的长度
- 返回值:
成功:返回发送成功的数据长度
失败: -1
- 接收(TCP/UDP, 服务器)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void \*buf, size_t len, int flags,
struct sockaddr \*src_addr, socklen_t \*addrlen);
用例
:
- sockfd:正在监听端口的套接口文件描述符,通过socket获得
- buf:接收缓冲区,往往是使用者定义的数组,该数组装有接收到的数据
- len:接收缓冲区的大小,单位是字节
- flags:填0即可
- src_addr:指向发送数据的主机地址信息的结构体,也就是我们可以从该参数获取到数据是谁发出的
- addrlen:表示第五个参数所指向内容的长度
- 返回值:
成功:返回接收成功的数据长度
失败: -1
6. 代码实现UDP
- udpClient.cpp
#include"udpClient.hpp"
void Usage(std::string proc)
{
std::cout<<"Usage: "<<proc<<" svr\_ip svr\_port"<<std::endl;
}
int main(int argc,char \*argv[])
{
if(argc != 3)
{
Usage(argv[0]);
exit(1);
}
udpClient uc(argv[1],atoi(argv[2]));
uc.initClient();
uc.start();
return 0;
}
- udpClient.hpp
#pragma once
#include<iostream>
#include<string>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<cstdlib>
class udpClient
{
public:
//Server ip , port;
udpClient(std::string _ip="127.0.0.1",int _port=8080)
:ip(_ip)
,port(_port)
{}
void initClient()
{
sock = socket(AF_INET,SOCK_DGRAM,0);
std::cout<<"sock"<<sock<<std::endl;
// struct sockaddr\_in local;
// local.sin\_family = AF\_INET;
// local.sin\_port = htons(port);
// local.sin\_addr.s\_addr = inet\_addr(ip.c\_str());
//
//
// if(bind(sock,(struct sockaddr\*)&local,sizeof(local)) < 0)
// {
// std::cerr<<"bind error!\n"<<std::endl;
// exit(1);
// }
}
void start()
{
// char msg[64];
std::string msg;
struct sockaddr\_in peer;
peer.sin_family = AF_INET;
peer.sin_port = htons(port);
peer.sin_addr.s_addr = inet\_addr(ip.c\_str());
while(1)
{
std::cout<<"Please Enter: ";
std::cin>>msg;
if(msg == "quit")
{
break;
}
sendto(sock,msg.c\_str(),msg.size(),0,(struct sockaddr\*)&peer,sizeof(peer));
char echo[128];
ssize_t s=recvfrom(sock,echo,sizeof(echo)-1,0,nullptr,nullptr);
echo[s]='\0';
if(s>0)
{
std::cout<<" server: "<<echo<<std::endl;
}
// msg[0]='\0';
// struct sockaddr\_in end\_point;
// socklen\_t len = sizeof(end\_point);
// ssize\_t s=recvfrom(sock,msg,sizeof(msg)-1,0,(struct sockaddr\*)&end\_point,&len);
// if(s>0)
// {
// msg[s]='\0';
// std::cout<<"Client :" << msg <<std::endl;
// std::string echo\_string = msg;
// echo\_string += " [server echo!]";
// sendto(sock,echo\_string.c\_str(),echo\_string.size(),0,(struct sockaddr\*)&end\_point,len);
// }
}
}
~udpClient()
{
close(sock);
}
private:
std::string ip;
int port;
int sock;
};
- udpServer.cpp
#include"udpServer.hpp"
void Usage(std::string proc)
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/ec5e12d539bf8537210a28723fa3130c.png)
![img](https://img-blog.csdnimg.cn/img_convert/6b133566f0df744fbb4f2f0cf334e8ac.png)
![img](https://img-blog.csdnimg.cn/img_convert/2649394141eb7412dd7c59b52c28cadc.png)
![img](https://img-blog.csdnimg.cn/img_convert/49aa1cce34d895dda86c29daf2a3f894.png)
![img](https://img-blog.csdnimg.cn/img_convert/720461e08127633ca228cc5df6938b7d.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)**
![img](https://img-blog.csdnimg.cn/img_convert/b037b587a30d503ec7a3b4d4fa116d87.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)
最全的Linux教程,Linux从入门到精通
======================
1. **linux从入门到精通(第2版)**
2. **Linux系统移植**
3. **Linux驱动开发入门与实战**
4. **LINUX 系统移植 第2版**
5. **Linux开源网络全栈详解 从DPDK到OpenFlow**
![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)
第一份《Linux从入门到精通》466页
====================
内容简介
====
本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。
![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)
**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**
> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
![img](https://img-blog.csdnimg.cn/img_convert/15aa934dfcc043711c640d2917cd10bf.jpeg)
8级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)
**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**
> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-yhrr09fX-1713037438274)]