【1】 IP分类
192.168.1.31 C类 , 点分十进制IP
C0A8011F 4*8 = 32位
104.243.29.189
IP分类:
A类:
第1字节为网络地址,其他3个字节为主机地址。第1字节的最高位固定为0;
0.0.0.0 - 127.255.255.255
B类:
128.0.0.0 - 191.255.255.255
C类:
192.0.0.0 - 223.255.255.255
D类: 224.0.0.0 - 239.255.255.255
E类:保留
============================================
42亿 70 80
IPv4: 点分十进制IP
IPv6:
192.168.1.0 - 192.168.1.255 => 256
(最多可以连接主机的个数为254,除网络地址0,广播地址255)
网络概念:
局域网可以理解为是一个小型网络;
若干个小型网络组合在一起可以组合成大型网络 => 以太网 ==> Inetnet因特网
=============================================
想把192.168.1.0该网段内IP分成4组,如何划分?
1)
子网掩码: (前面全是1,后面全是0)
255.255.255.0
1111 1111 1111 1111 1111 1111 0000 0000
网络号 主机号
2)
引入子网号的概念
4组: 00 01 10 11 => 2^2
修改子网掩码
1111 1111 1111 1111 1111 1111 1100 0000
255.255.255.192
3)
子网范围:
1: 192.168.1.1- 192.168.1.62
2: 192.168.1.65- 126
3: 192.168.1.129- 190
4: 192.168.1.193- 254
4个子网的IP是从1 - 254 (0 -255),并且这4类间不能直接通信的;
问题:
已知一个子网掩码号为255.255.255.192,问,最多可以连接多少台主机?
62台
256 - 192 = 64 - 2 = 62台
2^6 = 64 - 2 = 62台;
子网掩码:是一个32位的整数,作用是将某一个IP划分成网络地址和主机地址;
目的是合理的利用IP资源;
A类:
子网掩码: 255.0.0.0
B类:
子网掩码: 255.255.0.0
C类:
子网掩码: 255.255.255.0
===========================================================
【2】OSI模型
OSI模型是最理想的模型
物理层:传输的是bit流,物理信号,没有格式
链路层:格式变为帧
网络层:路由器中是有算法的,ip,(主机到主机)
传输层:端口号,数据传输到具体那个进程程序 (端到端)
会话层:通信管理,负责建立或者断开通信连接
表示层:确保一个系统应用层发送的消息可以被另一个系统的应用层读取,编码转换,数据解析,管理数据加密,解密;
应用层:指定特定应用的协议,文件传输,文件管理,电子邮件等。
【3】TCP/IP协议族
应用层 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet
传输层 TCP,UDP
网络层 IP,ICMP,RIP,OSPF,BGP,IGMP
网络接口与物理层 SLIP,CSLIP,PPP,ARP,RARP,MTU ISO2110,IEEE802.1,EEE802.2
【4】UDP TCP 协议相同点
都存在于传输层
TCP : 面向连接,可靠
TCP(即传输控制协议):
是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、
数据无失序、数据无重复到达的通信)
适用情况:
适合于对传输质量要求较高,以及传输大量数据的通信。
在需要可靠数据传输的场合,通常使用TCP协议
MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议
UDP : 无连接,不可靠
UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,
因为不需要进行连接,所以可以进行高效率的数据传输。
适用情况:
发送小尺寸数据(如对DNS服务器进行IP地址查询时)
在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
适合于广播/组播式通信中。
MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
【5】Socket
int sockfd;
//1.创建套接字文件
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err");
return -1;
}
printf("sockfd:%d\n", sockfd); sockfd = 3?
是一个编程接口;
返回一种特殊的文件描述符 (everything in Unix is a file)
【6】socket类型
流式套接字(SOCK_STREAM) TCP
提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
数据报套接字(SOCK_DGRAM) UDP
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
原始套接字(SOCK_RAW)
可以对较低层次协议如IP、ICMP直接访问。
【7】端口号(vi /etc/services)
为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别
TCP端口号与UDP端口号独立
端口号一般由IANA (Internet Assigned Numbers Authority) 管理
众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)
已登记端口:1024~49151
动态或私有端口:49152~65535
一般使用:6666 8888 7777 9999 10000 10001
sin_port
不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):
小端序(little-endian) - 低序字节存储在低地址
将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;
大端序(big-endian)- 高序字节存储在低地址
将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用
网络中传输的数据必须按网络字节序,即大端字节序
在大部分PC机上,当应用进程将整数送入socket前,需要转化成网络字节序;当应用进程从socket取出整数后,要转化成小端字节序)
如何检测字节序
方法一:使用指针
方法二:file命令,其中LSB的L代表小端存储
主机字节序转化网络字节序?
小端 转 大端
【8】 TCP编程流程
服务器端:
1.socket(),创建套接字文件,用于连接 sockfd(有一个属性默认是阻塞)
2) bind(), 绑定,把socket()函数返回的文件描述符和IP、端口号进行绑定;
3) listen(), (监听)将socket()返回的文件描述符的属性,由主动变为被动;
4) accept(), 阻塞函数,阻塞等待客户端的连接请求,如果有客户端连接,
则accept()函数返回,返回一个用于通信的套接字文件;
5) recv(), 接收客户端发来的数据; read()
6) send(), 发送数据;
7) close(), 关闭文件描述符;连接、通信
客户端:
1.socket(),创建套接字文件,既用于连接,也用于通信;
完成一个结构体的填充
- connect(); 用于发起连接请求;
- send(), 发送数据;
- recv(), 接收数据;
- close(), 关闭文件描述符;
【9】函数
1.socket
int socket(int domain, int type, int protocol);
功能: 创建套接字文件
参数:domain:协议族
AF_UNIX, AF_LOCAL 用于本地通信
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
type:协议类型
SOCK_STREAM(流式套接字) TCP
SOCK_DGRAM(数据包套接字) UDP
protocol:
一般情况下写0
系统默认自动帮助匹配对应协议
传输层:IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP
网络层:htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)
返回值:
成功: 返回一个文件描述符;
失败: -1
2.bind
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能: 绑定,将socket()返回值和IP/端口号进行绑定;
参数:
sockfd: 是socket()函数的返回值;
const struct sockaddr *addr:struct sockaddr是结构体类型,是一个通用结构体;
struct sockaddr {
sa_family_t sa_family; // 2个字节typedef unsigned short int sa_family_t; //
char sa_data[14]; // 14字节
}
整个结构体大小为16个字节
在填充的时候填充struct sockaddr_in ;
struct sockaddr_in {
unsigned short sin_family; //协议IPv4,2个字节
unsigned short sin_port; //端口号 ,2个字节 struct in_addr sin_addr;
struct in_addr {
__be32 s_addr; //IP地址,4个字节
};
/* Pad to size of `struct sockaddr’. */
unsigned char __pad[SOCK_SIZE - sizeof(short int) -
sizeof(unsigned short int) - sizeof(struct in_addr)];
//8个字节
};
addrlen:
结构体的大小;
sizeof(serveraddr);
返回值:
-1 失败
3.listen
int listen(int sockfd, int backlog);
功能: 用于监听,将主动套接字变为被动套接字;
参数:
sockfd: socket()的返回值
backlog:客户端同时连接服务器的最大个数;(队列1:保存正在连接)
(队列2,连接上的客户端)
5 6 7 8
返回值:
失败 -1
4.accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept(sockfd,NULL,NULL);
阻塞函数,阻塞等待客户端的连接请求,如果有客户端连接,
则accept()函数返回,返回一个用于通信的套接字文件;
参数:
sockfd
addr: 如果不需要关系具体是哪一个客户端,那么可以填NULL;
addrlen:如果不需要关系具体是哪一个客户端,那么可以填NULL;
返回值:
文件描述符;
acceptfd;
5.recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能: 接收数据
参数:
sockfd: acceptfd ;
buf 存放位置
len 大小
flags 一般填0,相当于read()函数
MSG_DONTWAIT
返回值:
< 0 失败出错
==0 表示客户端退出
>0 成功接收的字节个数
6.connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:用于连接服务器;
参数:
sockfd:socket函数的返回值
addr: 填充的结构体是服务器端的;
addrlen:结构体的大小
返回值 - 1 失败 正确 0
7.send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据
参数:
sockfd
buf
len
flags 如果填0,相当于write();
8.其他
inet_addr()
由点分十进制主机字节序转化为网络字节序(大端),返回转换后的地址。
inet_ntoa()
将32位网络字节序二进制地址转换成点分十进制的字符串。
主机字节序到网络字节序
u_long htonl (u_long hostlong);
u_short htons (u_short short);
网络字节序到主机字节序
u_long ntohl (u_long hostlong);
u_short ntohs (u_short short); //short 2字节
将字符串转换成主机字节序
int atoi(const char *nptr);