计算机网络基础
OSI参考模型及ISO参考模型
OSI 七层模型(理想模型)
应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
TCP/IP 四层模型(广泛应用)
应用层 传输层 网络层(Internet) 网络接口层(HW / 网卡)
对应关系
TCP/IP模型各层对应的协议
应用层协议:http ftp telnet
传输层协议(端口号工作在该层):TCP UDP
TCP 传输控制协议:
可靠协议, 建立在连接上(打电话),要求通信过程中有回应,才能说下一句话。
TCP占用网络资源更多,用在使用账户密码登录或者是对数据完整性有要求的时候
UDP 用户数据报协议:
不可靠协议, 不需要建立连接(发短信、写信)
看视频、QQ等聊天等对数据的及时性和完整性没有要求
如果TCP和UDP都能使用的场合,网络越差越应该使用UDP
port 端口号: (识别到底是哪个应用程序)源&目标
16位-- 2Byte short型
端口号一般由IANA管理
众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)如:ftp– 21,telnet-23,http(web)-80
动态或者私有端口 49151— 65535
注册端口 1024–49150
网络层: IPv4 IPv6 ICMP IGMP (IP)
网络接口层: ARP RARP MPLS
IP地址的划分
A 最高位为0, 只有最高字节表示网络,剩下字节表示主机
网络个数 0~ 0x7f
主机个数 0~0xffffff
0.0.0.0 表示本网络
127(即01111111)保留作为本机软件回路测试之用
地址范围 0.0.0.1~~~~ 126.255.255.255
对应的掩码(网络的字节数)255.0.0.0
B 最高位为10,最高两个字节表示网络,剩下字节表示主机
网络个数 0~ 0x3fff
主机个数 0~0xffff
地址范围 128.0.0.0 ~ 191.255.255.255
对应的掩码(网络的字节数)255.255.0.0
C 最高位为110,最高三个字节表示网络,剩下字节表示主机
网络个数 0~ 0x1fffff
主机个数 0~0xff
地址范围 192.0.0.0 ~ 223.255.255.255
对应的掩码(网络的字节数)255.255.255.0
(192.168.1.2 255.255.255.0都是判断依据)
D multicast 组播
二进制表示
11100000 00000000 00000000 00000000 ~ 11101111 11111111 11111111 11111111
转成十六进制
224.0.0.0 ~~ 239.255.255.255
另外还有broadcast 广播地址,最后一个字节为255
网络字节序(大端)
字符串与网络字节序的转换(转换IP)
- inet_aton
- inet_ntoa
inet_addr
int inet_aton(const char *cp, struct in_addr *inp); 转换网络主机地址cp为二进制数值,并存储在struct in_addr结构中,即第二个参数*inp,函数返回非0表示cp主机有地有效,返回0 表示主机地址无效。 char *inet_ntoa(struct in_addr in); 函数转换网络字节排序的地址为标准的ASCII以点分开的地址,,该函数返回指向点分开的字符串地址的指针,**该字符串的空间为静态分配的**, 这意味着在第二次调用该函数时,上一次调用将会被重写(复盖),所以如果需要保存该串最后复制出来自己管理! in_addr_t inet_addr(const char *cp); 该函数转换网络主机地址(如192.168.1.10)为网络字节序二进制值,如果参数char *cp无效,函数返回-1(INADDR_NONE), 这个函数在处理地址为255.255.255.255时也返回-1,255.255.255.255是一个有效的地址,不过inet_addr无法处理;
主机字节序与网络字节序的转换(转换端口号)
- htons (short针对两个字节的转换 )
- htonl (long 针对四个字节的转换)
- ntohs (short针对两个字节的转换)
- ntohl (long 针对四个字节的转换)
socket套接字
TCP协议C-S模型
UDP协议C-S模型
TUP/UDP函数实现
1、socket()函数
int socket(int domain, int type, int protocol);
domain 选择地址类型
IPv4 AF_INET
IPv6 AF_INET6
type SOCKET 类型
TCP SOCK_STREAM
UDP SOCK_DGRAM
protocol 一般为0 除非是用原始SOCKET
TCP:sockfd = socket(AF_INET,SOCK_STREAM,0);
UDP:sockfd =socket(AF_INET, SOCK_DGRAM,0);
2、bind()函数—将本地IP地址绑定到端口号
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
因为该结构体中的sa_data成员不知如何赋值
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
所以使用同长结构体
struct sockaddr_in //(注意网络字节序需要转换)
{
short int sin_family ;//地址族
unsigned short int sin_port ; 端口号 // 2 (别人如何找到我)
struct in_addr sin_addr; IP地址 // 如果是0.0.0.0(INADDR_ANY)表示本机IP
// 4 struct in_addr { in_addr_t s_addr;}; 是个32位无符号int , 大端
unsigned char sin_zero[8];
}
3、listen()、connect()函数
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求。
connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接。
4、accept()函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept函数的第一个参数为服务器的socket描述字,第二个参数为指向struct sockaddr *的指针,用于返回客户端的协议地址,第三个参数为协议地址的长度。如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字,代表与返回客户的TCP连接。
5、send ()、recv ()等函数
- send 往本进程的通信socket发送数据
- recv 从本进程的通信socket接收数据
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);
6、close()函数—关闭socket 结束通信
#include <unistd.h>
int close(int fd);