Socket与字节序

发布时间:2023年12月24日

一、Socket?

????????"Socket"(套接字)是计算机网络编程中的一个重要概念,它提供了一种在网络上进行进程间通信的机制。套接字是一种抽象,它允许程序通过网络发送和接收数据。在通常的情况下,套接字用于实现不同计算机之间的通信,但它也可以在同一台计算机内的不同进程之间进行通信。

???????所谓 socket (套接字),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处 的地位来讲, 套接字上联应用进程,下联网络协议栈 ,是应用程序通过网络协议进行通信的接口, 是应用程序与网络协议根进行交互的接口。
????????socket 可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它 是网络环境中进程间通信的 API ,也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 socket 中,该 socket 通过与网络接口卡( NIC )相连的传输介质将这段信息送到另外一台 主机的 socket 中,使对方能够接收到这段信息。 socket 是由 IP 地址和端口结合的 ,提供向应用层进程传送数据包的机制。
????????socket 本身有 插座 的意思,在 Linux 环境下,用于表示进程间网络通信的特殊文件类型。本质为内 核借助缓冲区形成的伪文件 。既然是文件,那么理所当然的,我们可以使用 文件描述符 引用套接 字。与管道类似的,Linux 系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。

?二、字节序

? ? ? ?现代 CPU 的累加器一次都能装载(至少) 4 字节(这里考虑 32 位机),即一个整数。那么这 4 字节在内存中排列的顺序将影响它被累加器装载成的整数的值,这就是字节序问题。在各种计算机 体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问 题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如 果不达成一致的规则,通信双方将无法进行正确的编码/ 译码从而导致通信失败。
???????字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序( 一个字节的数 据当然就无需谈顺序的问题了 )
????????字节序分为大端字节序(Big-Endian ) 和小端字节序( Little-Endian )。大端字节序是指一个整数的最高位字节(23 ~ 31 bit )存储在内存的低地址处,低位字节( 0 ~ 7 bit )存储在内存的高地址处;小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地址处。

#include <stdio.h> 
int main(){ 

union {
short value;//2字节
 char bytes[sizeof(short)];
}test; 

test.value 0x0102; 
if((test.bytes[0]=1)&&(test.bytes[1]=2)){ 
printf("大端字节序");}
else if((test.bytes[0]=2)&&(test.bytes[1]=1)){ 
printf(小端字节序") 
else printf("未知");
}

?

三、字节序转换函数?

????????当格式化的数据在两台使用不同字节序的主机之间直接传递时,接收端常必然错误的解释之。解决问题的方法是:发端总是把要发送的数据转换成大端字节序数据后再发送,而接收端知宜对方传送过来的数据总是采用大端字节序,以接收端可以根据自身采用的字节序决定是香对接收到的数据进行转换(小端机转换,大端机不转换)。

????????网络字节顺序(大端)是TCP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能被正确解释,网络字节顺序采用大端排序方式。 BSD Socket提供了封装的转换接口,方使程序员用。包括从主机字节序到络字节序的换函数: htons、htonl;从网络字节序到主机字节序的转换函数:ntohs、ntohl.

#include <stdio.h>
#include <arpa/inet.h>

int main(){
    
    // htons
    unsigned short a = 0x0102;
    unsigned short b = htons(a);
    printf("%x", b); 
    
// 如果你的机器是小端字节序,a在内存中的存储顺序是 02 01,而经过htons函数转换后,b在内存中的存储顺序是 01 02。

//如果你的机器是大端字节序,a在内存中的存储顺序是 01 02,而经过htons函数转换后,b在内存中的存储顺序是 02 01。

    //htonl转换IP 
    char buf[4]={192,168,1,100};
    int num *(int *)buf;
    int sum htonl(num);
    unsigned char *p (char *)&sum;
    printf("%d%d%d%d\n",*p,*(p+1),*(p+2),*(p+3));

// ntosl

    unsigned char buf1[4]{1,1,168,192}; 
    int num1 *(int *)buf1; 
    int sum1=ntohl(nm1);
    unsigned char *p1 (unsigned char *)&sum1; 
    printf("%d%d%d%d\n",*p1,*(p1+1),*(p1+2),*(p1+3)



    return 0; 
}

文章来源:https://blog.csdn.net/leimeili/article/details/135182853
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。