1. 1. Socket
  2. 2. 字节序
    1. 2.1. 为什么要有字节序?
    2. 2.2. 字节序的转换函数
  3. 3. socket地址
    1. 3.1. 通用socket地址
    2. 3.2. 专用socket地址

c++&&linux 网络编程

Socket

套接字,是对网络中不同主机上应用进程进行双向通信的抽象,表现为

IP Address:port

在linux中,为了同一接口,使得读写套接字和读写文件的操作一致,套接字被抽象为伪文件,因此在程序中可以借助文件描述符对其进行引用
套接字通信对服务器端和客户端进行了区分,需要注意,socket只是通信的接口,windows和linux都有socket,但存在细微的区别。

字节序

为什么要有字节序?

现代CPU的累加器一次可以加载多个字节的数据,即这四个字节在内存中的顺序将被影响它被累加器所装载城的整数的值,分为大端序(数据高位存在内存低位)和小端序(数据低位存在内存低位),因此,数据在跨计算机交互时,应约定好应该采用何种字节序

字节序的转换函数

使用套接字传输数据时候,约定统一采用网络字节序(即大端序),因此我们在发送时,应该采用字节序转换函数处理数据
如果主机已经是大端序,htonl和htons不会进行任何操作
h:host 主机字节序
network:网络字节序
s:short 一般为转换端口 16位
l:long 一般为转换ip 32位

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<arpa/inet.h>
int main()
{
unsigned short a=0x0102;
ubsigned short b=htons(a);
//此时b就是a的网络字节序版
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",*p,*(p+1),*(p+2),*(p+3));
//其他函数同理
}

socket地址

通用socket地址

1
2
3
4
5
6
#include<bits/socket.h>
struct sockaddr{
sa_family_t sa_family;//协议簇
char sa_data[14];//地址和端口
};
typedef unsigned short int sa_Family_t;
协议族 地址族 描述 含义和长度
PF_UNIX AF_UNIX unix本地域协议族 文件路径,最长可以达到108字节
PF_INET AF_INET TCP/IPv4协议族 16bit端口和32bit的ipv4,共6字节
PF_INET6 AF_INET6 TCP/IPv6协议族 16bit端口,32bit流表示,128bit IPv6地址,32bit范围ID,共26字节
由于sockaddr无法满足需求,linux定义了一个sockaddr_storage(了解即可)

专用socket地址

1
2
3
4
5
6
7
8
9
#include<netinet/in.h>
struct sockaddr_in{
sa_family_t sin_family;//协议族
in_port_t sin_port;//端口号 uint16_t
struct in_addr sin_addr;//地址
}
struct in_addr{
in_addr_t s_addr;//地址 uint32_t
}