==============================================================
第一天:基本概念、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



linux网络编程(一)的更多相关文章

  1. 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"

    [深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...

  2. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  3. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

  4. linux网络编程 no route to host 解决方案

    linux网络编程 no route to host 解决方案 [整合资料] (2013-05-13 21:38:12) 转载▼ 标签: net iptables it 分类: Linux 参考资料h ...

  5. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  6. Linux网络编程&内核学习

    c语言: 基础篇 1.<写给大家看的C语言书(第2版)> 原书名: Absolute Beginner's Guide to C (2nd Edition) 原出版社: Sams 作者: ...

  7. linux网络编程_1

    本文属于转载,稍有改动,以利于学习. (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...

  8. Linux网络编程入门 (转载)

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  9. Linux网络编程必看书籍推荐

    首先要说讲述计算机网络和TCP/IP的书很多. 先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的<计算机网络>第五版,这本书难易适中. &l ...

  10. [转] - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

随机推荐

  1. 【NLP学习其四】如何构建自己用于训练的数据集?什么是词性标注?

    数据集与词性标注 数据集是NLP中的重要一环. 但是提到数据集,很多人的第一个想法可能是:"这玩意从网上下载就好了,不用管". 真的不用管?最开始我也是这么认为的 于是我直奔CoN ...

  2. Spring Boot实现数据访问计数器

    1.数据访问计数器   在Spring Boot项目中,有时需要数据访问计数器.大致有下列三种情形: 1)纯计数:如登录的密码错误计数,超过门限N次,则表示计数器满,此时可进行下一步处理,如锁定该账户 ...

  3. 时间-i春秋

    记一道跑脚本的题 进入页面拿到一段代码. <?php header("content-type:text/html;charset=utf-8"); '天下武功唯快不破'; ...

  4. 用Autohotkey让Kitty命令行变得更好用

    下面的脚本实现Win+K键激活一个输入框,给出了kitty命令行常用的几种格式,基本可分为两种:连接保存好的模板(session)和完全手工连接,前者用-load加Session名称,后者需要在命令行 ...

  5. Special Forms and Syntax Sugars in Clojure

    (...): function literals, p40, 64; '(...): suppress evaluation, p24; _(...): comments, p18; ".. ...

  6. miniFTP项目集合

    项目简介 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务进 ...

  7. S3C2440—7.存储控制器访问外设

    文章目录 一.内存接口的概念 二.存储控制器(内存控制器) 2.1 什么是存储控制器? 2.2 S3C2440存储控制器介绍 2.3 存储控制器如何处理不同位宽的外设 2.4 怎么确定芯片的访问地址? ...

  8. redis的五大数据类型实现原理

    1.对象的类型与编码 Redis使用前面说的五大数据类型来表示键和值,每次在Redis数据库中创建一个键值对时,至少会创建两个对象,一个是键对象,一个是值对象,而Redis中的每个对象都是由 redi ...

  9. Docker中安装了gitlab,忘记了管理员密码,进行管理员密码重置

    重置docker中gitlab中root账号的密码 一.进入Docker的gitlab容器中 1.查看所有容器 docker ps 2.进入gitlab容器中 docker exec -it gitl ...

  10. 腾讯云TDSQL MySQL版 - 开发指南 分布式事务

    由于事务操作的数据通常跨多个物理节点,在分布式数据库中,类似方案即称为分布式事务. TDSQL MySQL版 支持普通分布式事务协议和 XA 分布式事务协议.TDSQL MySQL版(内核5.7或以上 ...