==============================================================
第一天:基本概念、TCP、FTP:
==============================================================

=========================================
*****************基本概念************
【1】计算机与网络发展的7个阶段
1 - 6略
7.
从“单纯建立连接”到“安全建立连接”(2010年)
【2】
1. 协议
一组控制数据通信的规则。
2. 标准
一致同意的规则。
分类:
事实上的标准:实际情况或者习惯
合法标准:法律或者规章制度
3. 标准化组织
缓慢发展:
ISO:国际标准化组织
ITU-T:国际电联-电信标准部
ANSI:美国国家标准化局
IEEE:电气电子工程师协会(主要是以太网、局域网方面的)
EIA:电子工业协会(物理传输标准、光钎传输)
快速发展:
论坛:帧中继论坛、ATM论坛
管理机构:FCC 联邦通信委员会
Internet标准:RFC
【3】
网络体系结构即指网络的层次结构和每层所使用协议的集合
【4】OSI开放系统互联模型

应用层
应用程序:FTP、E-mail、Telnet

表示层 数据格式定义、数据转换/加密
会话层 建立通信进程的逻辑名字与物理名字之间的联系

传输层
差错处理/恢复,流量控制,提供可靠的数据传输

网络层
数据分组、路由选择

数据链路层
数据组成可发送、接收的帧

物理层
传输物理信号、接口、信号形式、速率

OSI参考模型
1. ISO(国际标准化组织)制定了一个国际标准OSI(开放式通信系统互联参考模型),对通信系统进行了标准化。
2. OSI模型将通信协议中必要的功能分成了7层,每个分层都接收有它下一层所提供的特定服务,并且负责为自己的上一层提供特定的服务。
上下层之间进行交互时所遵循的约定叫做 “接口”

同一层之间的交互所遵循的约定叫做“协议”。
3. 7层通信
(1)应用层:指定特定应用的协议(比如发送和接受文件的软件按钮,发送者输入“早上好”并附上收件人,按下发送按钮,接受者收到信息会将其存储在硬盘或者非易失存储器(数据不会因为断电而丢失的一种存储设备)上,这些都是在应用层上的)
(2)表示层:
设备固有数据格式和网络标准数据格式的转换
(接受者和发送者如果使用的邮件客户端不一样,那么就会出现问题,如何实现用户之间的通信,那么就需要在表示层来起作用,
使得在不同的客户端上拥有相同的网络格式
(3)会话层:通信管理,负责建立或者断开通信连接(发送者一次性发送5份邮件,那么接受者如何接受,是一次性接受所有的文件然后断开连接还是没接受一次就断开,然后再次进行,发送者同理)
(4)传输层:管理两个节点(互联的网络中断)之间的数据传输。负责可靠传输(确保数据被可靠地传送到目标地址)(确保发送者和接受者之间的通信,会话层负责决定建立连接和断开连接的时机,而传输层进行实际的建立和断开处理)
(5)网络层:
地址管理与路由选择
,作用:在网络相互连接的环境中,将数据从发送端主机发送到接受端主机
(6)数据链路层:互连设备之间传送和识别
数据帧
(7)物理层:以“0”、“1”代表的电压的高低、灯光的闪灭<
比特流
>。界定连接器和网络的规格。
【5】
TCP/IP协议族
传输控制/网际协议(Transfer Control Protocol/Internet Protocol) 又称作网络通讯协议

应用层 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

TCP
(Transport Control Protocol)传输控制协议

UDP
(User Datagram Protocol)用户数据报协议

IP
(Internetworking Protocol)网间协议

SMTP
(Simple Mail Transfer Protocol)简单邮件传输协议

HTTP
(Hypertext Transfer Protocol) 超文本传输协议

FTP
(File Transfer Protocol)文件传输协议

ARP
(Address Resolution Protocol)地址解析协议

【6】
UDP和TCP
共同点:同为传输层协议
不同点:
TCP:有连接,可靠
UDP:无连接,不保证可靠

TCP(即传输控制协议)

是一种面向连接的传输层协议,
它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)

适用情况:

适合于对
传输质量要求较高
,以及
传输大量数据的通信
在需要可
靠数据传输
的场合,通常使用TCP协议
MSN/QQ等即时通讯软件的用户登录、账户管理相关的功能通常采用TCP协议

UDP(User Datagram Protocol)用户数据报协议

是不可靠的面向无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

适用情况:

发送小尺寸数据(如对DNS服务器进行IP地址查询时)
在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
适合于广播/组播式通信中。
MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
【7】
Socket

是一个编程接口

是一种特殊的文件描述符 (everything in Unix is a file)
并不仅限于TCP/IP协议
面向连接 (Transmission Control Protocol - TCP/IP)
无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX)

套接字类型:

流式套接字(SOCK_STREAM)

提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
-->TCP

数据报套接字(SOCK_DGRAM)

提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
-->UDP

原始套接字(SOCK_RAW)

可以对较低层次协议如IP、ICMP直接访问。
【8】IP地址
IP地址是Internet中主机的唯一标识
IP地址为32位(IPv4)或者128位(IPv6)
查看IP地址:
linux:ifconfig

dos:ipconfig

每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由

IPv4表示形式:
点分十进制形式
,如192.168.2.222,最后都会转换为一个32位的无符号整数。

IP地址分类(相对于ipv4的第一部分类区分(前八位))
A类 0000 0000 - 0111 1111 0.x.x.x - 127.x.x.x
B类 1000 0000 - 1011 1111 128.x.x.x - 191.x.x.x
C类 1100 0000 - 1101 1111 192.x.x.x - 223.x.x.x
D类 1110 0000 - 1110 1111 224.x.x.x - 239.x.x.x 表示组播地址
E类 1111 0000 - 1111 1111 240.x.x.x - 255.x.x.x 属于保留测试
192.168.x.x 属于局域网IP地址
127.x.x.x 属于自己的主机地址,一般用于自己主机通信使用
192.168.2.x
192.168.2.0 表示网段
192.168.2.255 表示广播地址
子网掩码:表示能够连接的主机的最大数
A类 255.0.0.0 2^24
B类 255.255.0.0 2^16
C类 255.255.255.0 2^8
实际:2^8 - 2 = 254


#include <arpa/inet.h>
将点分十进制IP地址转化为网络字节序的整型数据

in_addr_t inet_addr(const char *cp);
将网络字节序的整型数据转化为点分十进制IP地址

char *inet_ntoa(struct in_addr in);
一般是将accept填充的有关client的信息的结构体中提取IP并显示。

例子:
inet_addr("192.168.2.189");
【9】端口号
( vi /etc/services 查询占用的端口号)

为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别

TCP端口号与UDP端口号独立
端口号一般由IANA (Internet Assigned Numbers Authority) 管理
众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)
已登记端口:1024~49151
动态或私有端口:49152~65535

一般使用 6666 7777 8888 9999 10000 10001 10002

【10】字节序
不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO):

小端序(little-endian) - 低序字节存储在低地址

将低字节存储在起始地址,称为“Little-Endian”字节序,Intel、AMD等采用的是这种方式;

大端序(big-endian)- 高序字节存储在低地址

将高字节存储在起始地址,称为“Big-Endian”字节序,由ARM、Motorola等所采用

如何测试主机字节序:


方法1:使用指针
int a = 0x12345678;
char *p;
p = (char *)&a;
printf("a = %#x\n", a);
printf("*p = %#x\n", *p);

方法2:使用file命令
file a.out 其中LSB 的L代表小端存储
方法3:共用体
union un{
int a;
char b; };
myun.a = 0x12345678;
printf("a = %#x\n", myun.a);
printf("b = %#x\n", myun.b);

网络中传输的数据必须按网络字节序,即大端字节序


#include <arpa/inet.h>

将主机字节序转化为网络字节序

uint32_t
htonl(uint32_t hostlong);
uint16_t
htons(uint16_t hostshort);

将网络字节序转化为主机字节序

uint32_t
ntohl(uint32_t netlong);
uint16_t
ntohs(uint16_t netshort);



例子:
htons(9999);
【11】
ctags工具测创建和使用
第一步:添加索引文件
在/usr/include里面
执行sudo ctags -R,
生成一个tags文件
第二步:设置为全局
在家目录下的配置文件.vimrc中,添加
set tags+=/usr/include/tags
使用:

vim -t xxx 在系统内核当中查找xxx

ctrl + ] 追代码(Ctrl+鼠标左键)

ctrl + t 返回上一层(Ctrl+鼠标右键)


ctags:
sudo ctags -R
vim -t uint32_t :可以查看uint32_t 说明
=================================================

*****************TCP网络编程**************
【1】
流程
服务器:server.c
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
将套接字与服务器网络信息结构体绑定 bind( )
将套接字设置为监听模式 listen( )
阻塞等待客户端的连接请求 accept( )
进行通信 recv( )/send( )
客户端:client.c
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
发送客户端的连接请求 connect( )
进行通信 send( )/recv( )
【2】socket( )
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>


int socket(int domain, int type, int protocol);

功能:创建一个套接字,返回一个文件描述符
参数:
domain:通信域、协议族

AF_UNIX 本地通信

AF_INET 网络通信

AF_PACKET 底层通信
type:

SOCK_STREAM 流式套接字

TCP

SOCK_DGRAM 数据报套接字

UDP

SOCK_RAW 底层

protocol:协议,通常为0

返回值:
成功:文件描述符
失败:-1
例子:
int sockfd;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("fail to socket");
//return -1;
exit(1);
}
【3】bind( )
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

功能:将套接字与IP地址、端口号绑定
参数:
sockfd:
文件描述符,socket的返回值
addr:网络信息结构体
通用的:一般不用
struct sockaddr {
sa_family_t sa_family; 2个字节
char sa_data[14]; 14个字节
}

一般使用:sockaddr_in

#include <netinet/in.h>
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
==>
#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
==>
在函数宏里面,##代表字符串的拼接
sa_family_t
sin_family;
//地址族 AF_INET 2个字节
in_port_t
sin_port
; 端口号 2个字节
struct in_addr
sin_addr;

==>
struct in_addr
{
in_addr_t
s_addr
; ip地址 4个字节
};

这个没有用,为了使得sockaddr_in与sockaddr长度一致
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
addrlen:addr的长度
返回值:
成功:0
失败:-1
例子:

struct sockaddr_in serveraddr;


serveraddr.sin_family
= AF_INET;

serveraddr.sin_port
= htons(9999);

serveraddr.sin_addr.s_addr
= inet_addr("192.168.2.189");

if(bind(sockfd,

(struct sockaddr *)&serveraddr
, sizeof(struct sockaddr)) < 0)

{
perror("fail to bind");
exit(1);
}
【4】listen( )
#include <sys/types.h>
#include <sys/socket.h>

int listen(int sockfd, int backlog);

功能:将套接字设置为被动监听状态
参数:

sockfd:文件描述符,socket的返回值

backlog:允许同时响应客户端请求的个数,一般设置为5,10

返回值:
成功:0
失败:-1
例子:
if(listen(sockfd, 5) < 0)
{
perror("fail to listen");
exit(1);
}
【5】accept( )
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

功能:阻塞等待客户端的连接请求
参数:
sockfd:文件描述符,socket的返回值
addr:
网络信息结构体(自动填充的客户端的网络信息结构体)
addrlen:addr的长度
返回值:
成功:新的文件描述符(用于与客户端通信)
失败:-1
例子:

struct sockaddr_in clientaddr;

socklen_t addrlen = sizeof(clientaddr);
if(accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen) < 0)
{
perror("fail to accept");
exit(1);
}
【6】connect( )
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数:
sockfd:文件描述符,socket的返回值
addr:
服务器的网络信息结构体(需要自己填充)
addrlen:addr的长度
返回值:
成功:0
失败:-1
例子:

if(connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)

{
perror("fail to connect");
exit(1);
}
【7】send( )
#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

功能:发送数据
参数:
sockfd:文件描述符

服务器:accept的返回值(用于向客户端发送)

客户端:socket的返回值(用于向服务器器发送
buf:发送的数据
len:数据的长度
flags:标志位

0 阻塞

MSG_DONTWAIT 非阻塞
返回值:
成功:发送的数据的长度
失败:-1
【8】recv( )
#include <sys/types.h>
#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

功能:接收数据
参数:
sockfd:文件描述符

服务器:accept的返回值

客户端:socket的返回值
buf:接收的数据
len:数据的长度
flags:标志位


0 阻塞

MSG_DONTWAIT 非阻塞
返回值:
成功:接收的数据的长度
0 :
发送端异常退出或者关闭文件描述符
失败:-1



最新文章

  1. Vue + Webpack + Vue-loader 系列教程(1)功能介绍篇
  2. 项目积累(三)CSS
  3. JSP导入EXCEL样式
  4. 【leetcode】Subsets II
  5. UI学习笔记---第十一天UITableView表视图高级-自定义cell
  6. ActionContext详解
  7. Hololens开发笔记之Gesture手势识别(基本介绍)
  8. ubuntu 配置TFTP和NFS
  9. 【J2EE】Java连接SQL Server 2000问题:“com.microsoft.sqlserver.jdbc.SQLServerException:用户&#39;sa&#39;登录失败。该用户与可信SQL Server连接无关联”
  10. LetterView实现载入全国各地城市
  11. Logback日志配置的简单使用
  12. win10下配置php环境变量
  13. java集合框架之ArrayList
  14. (BST 递归) leetcode98. Validate Binary Search Tree
  15. [Swift]LeetCode883. 三维形体投影面积 | Projection Area of 3D Shapes
  16. 使用PHPExcel导出数据库表结构及内容
  17. BZOJ 3498: PA2009 Cakes 一类经典的三元环计数问题
  18. JAVA四大域对象总结
  19. PHP安全之Web攻击(转)
  20. SpringBoot(十一)过滤器和拦截器

热门文章

  1. 未知高度-纯css实现水平垂直居中
  2. C++ //运算符重载 +号
  3. Docker入门第三章
  4. 自己动手实现Lua--实现TAILCALL指令
  5. 【大咖直播】Elastic Security 安全管理实战工作坊
  6. 解决微信官方SDK给出1.4.0等版本没有预览文件(previewFile)等接口
  7. 网络安全学习阶段性总结:SQL注入|SSRF攻击|OS命令注入|身份验证漏洞|事物逻辑漏洞|目录遍历漏洞
  8. Mysql报错注入之floor报错详解
  9. VLAN-3 Hybrid接口应用
  10. SQL 练习40