Linux网络编程——预备知识
Posted 朱果果
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux网络编程——预备知识相关的知识,希望对你有一定的参考价值。
1.Socket
1.1、socket是一个应用编程接口,是一种特殊的文件描述符(可对其执行IO操作,open、write、close)
一个文件描述符指向一个套接字,该套接字内部由内核借助两个缓冲区实现。
1.2、socket代表网络编程的一种资源
1.3、socket的类型
流式套接字(SOCK_STREAM):唯一对应TCP
提供一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收,内置流量控制,避免数据流
淹没慢的接收方,数据流被看作字节流,无长度限制。
数据报套接字(SOCK_DGRAM):唯一对应UDP
提供无连接服务、数据包以独立数据包的形式发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
原始套接字(SOCK_RAM):对应多个协议,发送穿透了传输层
可以对较低层协议如IP、ICMP直接访问
2、IP地址
2.1、IP地址是Internet中主机的1标识
— Internet中主机要与别的主机通信必须要有一个IP地址
— IP地址为32位(IPV4),或128位(IPV6)
— 每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由
2.2、表示形式
—常用点分形式,如196.128.1.2
—32位整数
特殊IP地址:
—局域网IP:192.xxx.xxx.xxx 10.xxx.xxx.xxx
—广播IP:xxx.xxx.xxx.255 255.255.255.255(全网广播)
—组播IP:224.xxx.xxx.xxx ~ 239.xxx.xxx.xxx
3.端口号
为了区分一台主机接收到的数据包应交由哪个任务进行处理,使用端口号来区别
TCP 端口号与UDP端口号独立
端口号一般由INAN(Internet assigned numbers authority)管理
—众所周知端口:1--1023(1~255为众所周知端口,256~1023端口通常有UNIX系统占用)
—注册端口:1024~50000
—动态或私有端口: 50000~65535
网络里的通信是由 IP地址 + 端口号来决定的
4.字节序
4.1 主机字节序
字节序是指 整数 在内存中保存的顺序,是指不同的CPU访问内存中的多字节数据时,存在大小端问题。
(若CPU访问的是字符串,则不存在大小端问题。)
主机字节序(host-byte)指的是处理器存储数据的字节顺序。
eg: 0X 12345678 (0X 高位------低位)
最常见的有两种:
1.Little endian:将低序字节存储在起始地址——LE
2.Big endian:将高序字节存储在起始地址 ——BE
一般来说:
X86 / ARM : 小端模式
Powerpc / mips:大端模式
1 #include <stdio.h> 2 #include <arpa/inet.h> 3 4 int main(){ 5 6 unsigned long a = 0x12345678; 7 unsigned char *p = (unsigned char *)(&a); 8 9 printf("主机字节序:%0x %0x %0x %0x\\n", p[0], p[1], p[2], p[3]); 10 11 unsigned long b = htonl(a); //将主机字节序转化成了网络字节序 12 13 p = (unsigned char *)(&b); 14 15 printf("网络字节序:%0x %0x %0x %0x\\n", p[0], p[1], p[2], p[3]); 16 return 0; 17 } 18 ———————————————— 19 源程序链接:https://blog.csdn.net/msdnwolaile/article/details/50727653
4.2 网络字节序
网络字节序(network-byte)指的是网络编程时,存储数据的字节顺序。在网络编程时用到的IP地址和端口号都需要网络字节序。
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节
与“主机字节序”相反,网络字节序将数据的重要部分保存在低地址,不重要的部分保存到高地址。
由于不同机器采用的字节序大小端可能不同,所以在传输数据的过程中,中间需要一个标准化的数据格式即网络字节序。
a的固有数据存储-------标准化--------转化成b的固有格式 ——> a的主机字节序----------网络字节序 ---------b的主机字节序
4.3 转换函数
可以通过一系列的函数实现主机字节序和网络字节序之间的转换。
函数中的h表示主机host,n表示网络networ,l表示长整形long,s表示短整形short。
1 /****主机字节序--->网络字节序****/ 2 uing16_t htons(uint16_t short); 3 uint32_t htonl(uint32_t hostlong); 4 5 /****网络字节序---->主机字节序****/ 6 uint16_t ntohs(uint16_t netshort); 7 uint32_t ntohl(uint32_t netlong);
IP地址转换函数:
1 #include <arpa/inet.h> 2 3 in_addr_t inet_addr(const char *cp); 4 //net_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE 5 //特点: 1、仅适用于IPV4 6 // 2、出错返回-1 7 // 3、此函数不能用于255.255.255.255的转换 8 9 int inet_pton(int af, const char *src, void *dst) ; 10 //参数: af---地址协议族(AF_INST和AF_INET6) 11 // src--是一个指针(填写点分形式的IP地址,IPV4) 12 // dst--转换的结果给dst 13 //特点: 1、适应于IPV4和IPV6 14 // 2、能正确处理255.255.255.255的转换 15 // 16 inet_ntop();
1 #include <stdio.h> 2 #include <arpa/inet.h> 3 4 int main() 5 { 6 struct in_addr ipaddr; 7 unsigned long addr = inet_addr("192.168.1.100"); 8 printf("addr = %u\\n", ntohl(addr)); 9 10 ipaddr.s_addr = addr; 11 printf("%s\\n", inet_ntoa(ipaddr)); 12 return 0; 13 } 14 ———————————————— 15 源程序: 16 https://blog.csdn.net/msdnwolaile/article/details/50727653
结果:
以上是关于Linux网络编程——预备知识的主要内容,如果未能解决你的问题,请参考以下文章
Linux篇第十八篇——网络套接字编程(预备知识+UDP套接字的编写)