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); char buf[4]={192,168,1,100}; int num=*(int*)buf; int sum=htonl(num); unsigned char *p=(char*)∑ 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; struct in_addr sin_addr; } struct in_addr{ in_addr_t s_addr; }
|