您的位置:首页 > 游戏 > 手游 > linux网络编程2

linux网络编程2

2024/12/23 8:27:56 来源:https://blog.csdn.net/qq_65818377/article/details/142342497  浏览:    关键词:linux网络编程2

24.9.18学习目录

  • 一.数据包的传送
    • 1.数据包在每层间的传送
    • 2.链路层的封包
    • 3.网络层、传输层封包格式
  • 二.字节序
    • 1.概念
    • 2.字节序转换函数
  • 三.IP地址转换
  • 四.UDP
    • 1.概述
    • 2.网络编程接口socket
    • 3.UDP的C/S架构
    • 4.UDP编程

一.数据包的传送

1.数据包在每层间的传送

传送方数据从运用层到链路层间都会添加信息,确保数据的能准确传入到接收方,而接受发从链路层到运用层会对添加的数据进行验证并删除
在这里插入图片描述

2.链路层的封包

封包的类型主要为两个,但常用的是以太网封装方法
目的地址和源地址都是MAC地址
类型指的是采用什么类型的协议
在这里插入图片描述
以太网常用在有线局域网;
IEEE常用在无线局域网;

3.网络层、传输层封包格式

其添加的数据如图中,每一行都占4个字节
在这里插入图片描述

二.字节序

1.概念

字节序是指多字节数据的存储顺序
在数据传输过程中字节序的不同会导致信息接收时理解错误,因此需要注意接收方和传送方的字节序

分类:
小端格式:将低位字节数据存储在低地址
大端格式:将高位字节数据存储在低地址

高地址为MSB;低地址为LSB


判断字节的存储方式:
#include <stdio.h>union un
{int a;char b;
};int main(int argc,char const *argv[])
{union un myun;myun.a = 0x12345678;printf("a = %#x\n",myun.a);printf("b = %#x\n",myun.b);if(myun.b = 0x78){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

注意:

  • 网络协议指定了通讯字节序为大端
  • 只有在多字节数据处理时才需要考虑字节序
  • 运行在同一台计算机上的进程互相通信时,一般不用考虑字节序
  • 异构计算机之间通讯,需要转换自己的字节序为网络字节序,可以通过特定的函数进行转换

2.字节序转换函数

(1)转换为网络字节序函数

#include <arpa/inet.h>
//长整型
uint32_t htonl(uint32_t hostint32);//短整型
uint16_t htons(uint16_t hostint16);

(2)转换为主机字节序函数

#include <arpa/inet.h>
//长整型
uint32_t ntohl(uint32_t hostint32);//短整型
uint16_t ntohs(uint16_t hostint16);

三.IP地址转换

将用户识别的IP(为字符串)转换为机器能识别的整型

(1)地址间的相互转换:

#include <arpa/inet.h>
//将点分十进制字符串转换为32为无符号整数
int inet_pton(int family,const char *strptr,void *addrptr)

family:协议族,有AF_INET为IPV4的网络协议、AF_INET6
    为IPV6的网络协议
strptr:点分十进制字符串
addrptr:32位无符号整数的地址

#include <arpa/inet.h>
//将32位无符号整数转换为点分十进制字符串
const char *inet_ntop(int family,const void *addrptr,char *strptr,size_t len);

len:为strptr缓冲区长度

(2)用于IPV4地址的转换的函数
该两个函数在TCP和UDP网络编程中比较常用

#include <sys/sochet.h>
#include <netinet/in.h>
#include <arpa/inet.h>//将点分十进制字符串转换为整数
int_addr_t inet_addr(const char *cp)//将整数转换为点分十进制字符串
char *inet_ntoa(struct in_addr in);

cp:为点分十进制的IP地址

in:为保存IP地址的结构体

四.UDP

1.概述

常用于语音和视频通话

特定:

  • 相较于TCP速度稍快些
  • 简单的请求、应答应用程序可以使用UDP
  • 对于海量数据传输不应该使用UDP
  • 广播和多播应用必须使用UDP

2.网络编程接口socket

socket(也称套接字)提供不同主机上的进程之间的通信;
其是一种文件描述符。代表了一个通信管道的一个端点;
对其操作类似于文件的操作,使用read、write等函数;
获取socket的方法为socket();

socket主要分类:

  • SOCK_STREAM:流式套接字,用于TCP
  • SOCK_DGRAM:数据报套接字,用于UDP
  • SOCK_RAW:原始套接字,对于其他层次的协议操作时需要使用这个类型

3.UDP的C/S架构

UDP网络编程流程:

(1)服务器:
使用socket()函数创建socket;
是用bind()函数将服务器的ip地址、端口号和socket进行绑定;
使用recvfrom()函数等待接收用户请求的发送;
使用sendto()函数给用户发送数据;

(2)客户端:
使用socket()函数创建socket;
使用sendto()函数给服务器发送数据;
使用recvfrom()函数接收服务器发送的数据;
使用close()函数关闭socket

4.UDP编程

(1)socket函数创建socket

#include <sys/socket.h>
int socket(int family,int type,int protocol);

type:套接字类型
protocol:协议类别,有0、IPPROTO_TCP、IPPROTO_UDP等

特点:
创建socket时,系统不分配端口
创建的socket时指定发起服务的请求,当作为服务器时,需要将其该为被动的

(2)IPv4套接字地址结构
注意:
不同格式地址能被传入套接字函数,地址必须要强制转换成通用套接字地址结构体,因为不同场合使用的结构体不一样,但调用的函数是一样的;

以下三个在linux中都已经定义好了,能直接使用

#include <netinet/in.h>
struct in_addr
{in_addr_t s_addr;//IP地址
};//网络编程中通用协议
//在定义源地址和目的地址时,使用下面结构体
struct socketaddr_in
{sa_family_t sin_family;//协议族in_port_t sin_port;//端口号struct in_addr sin_addr;//ip地址char sin_zero[8];//填充
};//通用的地址结构体
struct sockaddr
{sa_family_t sa_family;//协议族char sa_data[14];//填充
};

当调用编程接口函数,且该函数需要传入地址结构时需要进行强制转换

bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr));

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com