Linux网络编程——千峰物联网笔记

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux网络编程——千峰物联网笔记相关的知识,希望对你有一定的参考价值。

B站视频:千峰物联网学科linux网络编程
网址:https://www.bilibili.com/video/BV1RJ411B761?p=1

目录

第一章:计算机网络概述

1.1计算机网络发展简史

1.1.1最早的广域网

在通信双方或多方之间,通过电路交换建立电路连接的网络

1.1.2电路交换网特点

1、建立链接->使用链接->释放链接
2、物理通路被通信双方独占
计算机数据是突发式出现在数据链路上的,而电路交换网的建立链接、使用链接、释放链接的三个过程使得传输效率太低,故电路交换不适合传输计算机数据。

1.1.3计算机网络的要求

1957年10月4日,苏联发射了世界上第一颗人造地球卫星——Sputnik
针对Sputnik所带来的威胁,美国国会于1958年1月7日拨款成立ARPA(the Advanced Research Projects Agency 美国高级研究计划署)
对计算机网络的要求
1、不是为了打电话
2、结构简单,可靠的传输数据
3、能够连接不同种类的计算机
4、所有网络节点同等重要
5、必须有冗余的路由

1.1.4分组交换

通过标有地址的分组进行路由选择传送数据,使通信通道仅在传送期间被占用的一种交换方式
分组的组成:
每个分组都由首部和数据段组成;为什么?

1.1.5交换方式

交换方式—存储转发
节点收到分组,先暂时存储下来,再检查其首部,按
照首部中的目的地址,找到合适的节点转发出去

特点:
1、以分组作为传输单位
2、独立的选择转发路由
3、逐段占用,动态分配传输带宽
想一想:节点收到的分组有序吗?

1.1.6因特网发展史

从单个ARPANET向因特网发展的过程
1983年TCP/IP协议成为APRANET的标准协议

1.1.6.1三级结构的因特网
(NSFNET国家科学基金网)
围绕六台大型计算机中心建设起来的计算机网络
主干网、地区网、校园网

1.1.6.2多级结构因特网
NSFNET逐步被商用因特网主干网替代

1.2 TCP/IP协议简介

为了使各种不同的计算机之间可以互联,ARPANet指定了一套计算机通信协议,即TCP/IP协议(族)

应用领域


为了减少协议设计的复杂性,大多数网络模型均采用分层的方式来组织
每一层利用下一层提供的服务来为上一层提供服务
本层服务的实现细节对上层屏蔽

1.2.1分层结构

应用层:应用程序间沟通的层
例如:FTP、Telnet、HTTP等
传输层:提供进程间的数据传送服务
负责传送数据,提供应用程序端到端的逻辑通信
例如:TCP、UDP
网络层:提供基本的数据封包传送功能
最大可能的让每个数据包都能够到达目的主机
例如:IP、ICMP等
链路层:负责数据帧的发送和接收

每层完成自己的任务,最终通过不同层次的处理完成数据的收发


1.2.2 IP协议简介

特指为实现在一个相互连接的网络系统上从源地址到目的地传输数据包(互联网数据包)所提供必要功能的协议
特点:
不可靠:它不能保证IP数据包能成功地到达它的目的地,仅提供尽力而为的传输服务
无连接:IP并不维护任何关于后续数据包的状态信息。每个数据包的处理是相互独立的。IP数据包可以不按发送顺序接收
IP数据包中含有发送它主机的IP地址(源地址)和接收它主机的IP地址(目的地址)

1.2.3 TCP协议简介

TCP是一种面向连接的,可靠的传输层通信协议
功能:
提供不同主机上的进程间通信
特点
1、建立链接->使用链接->释放链接(虚电路)
2、TCP数据包中包含序号和确认序号
3、对包进行排序并检错,而损坏的包可以被重传
服务对象
需要高度可靠性且面向连接的服务
如HTTP、FTP、SMTP等

1.2.4 UDP协议简介

UDP是一种面向无连接的传输层通信协议
功能:
提供不同主机上的进程间通信
特点
1、发送数据之前不需要建立链接
2、不对数据包的顺序进行检查
3、没有错误检测和重传机制
服务对象
主要用于“查询—应答”的服务
如:NFS、NTP、DNS等

1.3 MAC地址、IP地址、Netmask、端口

1.3.1 网卡

又称为网络适配器或网络接口卡NIC,但是现在更多的人愿意使用更为简单的名称“网卡”
通过网卡能够使不同的计算机之间连接,从而完成数据通信等功能

1.3.2 mac地址

MAC地址,用于标识网络设备,类似于身份证号,且理论上全球唯一
组成:以太网内的MAC地址是一个48bit的值

1.3.3 IP地址

IP地址是一种Internet上的主机编址方式,也称为网际协议地址
1.3.3.1 ip地址组成
使用32bit,由网络ID,主机ID两部分组成
子网ID:IP地址中由子网掩码中1覆盖的连续位
主机ID:IP地址中由子网掩码中0覆盖的连续位

1.3.3.2 ip地址特点
子网ID不同的网络不能直接通信,如果要通信则需要路由器转发
主机ID全为0的IP地址表示网段地址
主机ID全为1的IP地址表示该网段的广播地址

1.3.3.3 ip地址分类如下:
A类地址:默认8bit子网ID,第一位为0
B类地址:默认16bit子网ID,前两位为10
C类地址:默认24bit子网ID,前三位为110
D类地址:前四位为1110,多播地址
E类地址: 前五位为11110,保留为今后使用
A,B,C三类地址是最常用的

公有IP(可直接连接Internet)
经由InterNIC所统一规划的IP
私有IP(不可直接连接Internet )
主要用于局域网络内的主机联机规划

1.3.3.4回环ip地址
通常 127.0.0.1 称为回环地址

功能
主要是测试本机的网络配置,能ping通127.0.0.1说
明本机的网卡和IP协议安装都没有问题
注意
127.0.0.1~127.255.255.254中的任何地址都将回环到本地主机中
不属于任何一个有类别地址类,它代表设备的本地虚拟接口

1.3.3.5 ip地址设置
linux:ifconfig eth0 192.168.1.1
windows:

自动获取网络参数(DHCP)
在局域网内会有1台主机负责管理所有的计算机网络参数,当PC启动时就会主动向服务器要求IP参数,若PC获取到服务器给的网络相关参数,那么就可以使用网络功能了进行通信
windows中:如图

在linux中重新获取ip的方式:
sudo dhclient

通过拨号取得
向ISP申请注册,直接拨到ISP,ISP会自动设置电脑的正确的网络参数
windows:如图

linux:
sudo pppoeconf
sudo pon dsl-provider //拨号ADSL
sudo poff //断开ADSL

1.3.4 子网掩码

子网掩码(subnet mask)又叫网络掩码、地址掩码是一个32bit由1和0组成的数值,并且1和0分别连续
作用
指明IP地址中哪些位标识的是主机所在的子网以及哪些位标识的是主机号
特点
必须结合IP地址一起使用,不能单独存在
IP地址中由子网掩码中1覆盖的连续位为子网ID,其余为主机ID

子网掩码的表现形式
192.168.220.0/255.255.255.0
192.168.220.0/24
手动进行配置如下(linux)

1.3.5端口

1.3.5.1 端口概述
TCP/IP协议采用端口标识通信的进程
用于区分一个系统里的多个进程
特点
1、对于同一个端口,在不同系统中对应着不同的进程
2、对于同一个系统,一个端口只能被一个进程拥有
3、一个进程拥有一个端口后,传输层送到该端口的数据全部被该进程接收,同样,进程送交传输层的数据也通过该端口被送出
1.3.5.2端口号
类似pid标识一个进程;在网络程序中,用端口号(port)来标识一个运行的网络程序
特点
1、端口号是无符号短整型的类型
2、每个端口都拥有一个端口号
3、TCP、UDP维护各自独立的端口号
4、网络应用程序,至少要占用一个端口号,也可以占有多个端口号
想一想
为什么有了pid,还需要端口来标识一个进程呢?

知名端口(1~1023)
由互联网数字分配机构(IANA)根据用户需要进行统一分配
例如:FTP—21,HTTP—80等
服务器通常使用的范围;若强制使用,须加root特权
动态端口(1024~65535)
应用程序通常使用的范围
注意
端口号类似于进程号,同一时刻只能标志一个进程
可以重复使用

1.4数据包的组装、拆解

1.4.1数据包在各个层之间的传输

1.4.2链路层封包格式

注意
1、IEEE802.2/802.3封装常用在无线
2、以太网封装常用在有线局域网

1.4.3网络层、传输层封包格式

1.5网络应用程序开发流程

1.5.1 TCP—面向连接

电话系统服务模式的抽象
每一次完整的数据传输都要经过建立连接、使用连接、终止连接的过程
本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同
保证数据传输的可靠性

1.5.2 UDP—面向无连接

邮件系统服务模式的抽象
每个分组都携带完整的目的地址
不能保证分组的先后顺序
不进行分组出错的恢复和重传
不保证数据传输的可靠性

无论采用面向连接的还是无连接,两个进程通信过程中,大多采用C/S架构
client向server发出请求,server接收到后提供相应的服务
在通信过程中往往都是client先发送请求,而server等待请求然后进行服务

1.5.3 C/S架构示例(面向连接)

server工作过程
打开一通信通道并告知本地主机,它愿意在一特定端口(如80)上接收客户请求
等待客户请求到达该端口
接收客户请求,并发送应答信号,激活一新的线程处理这个客户请求
服务完成后,关闭新线程与客户的通信链路

client工作过程
打开一通信通道并连接到服务器特定端口
向服务器发出服务请求,等待并接收应答
根据需要继续提出请求
请求结束后关闭通信通道并终止

第二章:UDP编程

2.1编程准备-字节序、地址转换

2.1.1字节序概述

字节序概念
是指多字节数据的存储顺序
分类
小端格式:将低位字节数据存储在低地址
大端格式:将高位字节数据存储在低地址
注意
LSB:低地址
MSB:高地址
想一想
怎样确定主机的字节序?

确定主机字节序程序
#include<stdio.h>
union
short s;
char c[sizeof(short)];
un;
int main()

un.s =0x0102;
if((un.c[0]==1)&&(un.c[1]==2))

printf(“big-endian\\n”);

if((un.c[0]==2)&&(un.c[1]==1))

printf(“little-endian\\n”);

return 0;

特点
1、网络协议指定了通讯字节序—大端
2、只有在多字节数据处理时才需要考虑字节序
3、运行在同一台计算机上的进程相互通信时,一般不用考虑字节序
4、异构计算机之间通讯,需要转换自己的字节序为网络字节序
在需要字节序转换的时候一般调用特定字节序转换函数

2.1.2 htonl函数

uint32_t htonl(uint32_t hostint32);
功能:
将32位主机字节序数据转换成网络字节序数据
参数:
hostint32:待转换的32位主机字节序数据
返回值:
成功:返回网络字节序的值
头文件:
#include <arpa/inet.h>

2.1.3 htons函数

uint16_t htons(uint16_t hostint16);
功能:
将16位主机字节序数据转换成网络字节序数据
参数:
uint16_t:unsigned short int
hostint16:待转换的16位主机字节序数据
返回值:
成功:返回网络字节序的值
头文件:
#include <arpa/inet.h>

2.1.4 ntohl函数

uint32_t ntohl(uint32_t netint32);
功能:
将32位网络字节序数据转换成主机字节序数据
参数:
uint32_t: unsigned int
netint32:待转换的32位网络字节序数据
返回值:
成功:返回主机字节序的值
头文件:
#include <arpa/inet.h>

2.1.5 ntohs函数

uint16_t ntohs(uint16_t netint16);
功能:
将16位网络字节序数据转换成主机字节序数据
参数:
uint16_t: unsigned short int
netint16:待转换的16位网络字节序数据
返回值:
成功:返回主机字节序的值
头文件:
#include <arpa/inet.h>

示例:

结果:

2.1.6地址转换函数

2.1.6.1 inet_pton函数
字符串ip地址转整型数据
int inet_pton(int family,const char *strptr, void *addrptr);
功能:
将点分十进制数串转换成32位无符号整数
参数:
family 协议族
strptr 点分十进制数串
addrptr 32位无符号整数的地址
返回值:
成功返回1 、 失败返回其它
头文件:
#include <arpa/inet.h>

例:
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])

char ip_str[] = “10.0.13.100”;
unsigned int ip_uint = 0;
unsigned char * ip_p =NULL;//可以用char吗?

inet_pton(AF_INET,ip_str,&ip_uint);
printf("ip_uint = %d\\n",ip_uint);

ip_p = (unsigned char *) &ip_uint;
printf("ip_uint = %d.%d.%d.%d\\n",*ip_p,*(ip_p+1),*(ip_p+2),*(ip_p+3));

return 0;

运行结果:

2.1.6.2inet_ntop函数
整型数据转字符串格式ip地址
const char *inet_ntop(int family, const void *addrptr,
char *strptr, size_t len);
功能:
将32位无符号整数转换成点分十进制数串
参数:
family 协议族
addrptr 32位无符号整数
strptr 点分十进制数串
len strptr缓存区长度
len的宏定义
#define INET_ADDRSTRLEN 16 //for ipv4
#define INET6_ADDRSTRLEN 46 //for ipv6
返回值:
成功:则返回字符串的首地址
失败:返回NULL
头文件:
#include <arpa/inet.h>

例:
#include<stdio.h>
#include<arpa/inet.h>
int main()

unsigned char ip[]=10,0,13,252;
char ip_str[16];
inet_ntop(AF_INET,(unsigned int *)ip,ip_str,16);
printf(“ip_str = %s\\n”,ip_str);
return 0;

运行结果:

2.2 UDP介绍、编程流程

2.2.1 UDP概述

UDP协议
面向无连接的用户数据报协议,在传输数据前不需要先建立连接;目地主机的运输层收到UDP报文后,不需要给出任何确认
UDP特点
1、相比TCP速度稍快些
2、简单的请求/应答应用程序可以使用UDP
3、对于海量数据传输不应该使用UDP
4、广播和多播应用必须使用UDP
UDP应用
DNS(域名解析)、NFS(网络文件系统)、RTP(流媒体)等

2.2.2网络编程接口socket

网络通信要解决的是不同主机进程间的通信
1、首要问题是网络间进程标识问题
2、以及多重协议的识别问题
20世纪80年代初,加州大学Berkeley分校在BSD(一个UNIX OS版本)系统内实现了TCP/IP协议;其网络程序编程开发接口为socket
随着UNIX以及类UNIX操作系统的广泛应用, socket成为最流行的网络程序开发接口

socket作用
提供不同主机上的进程之间的通信
socket特点
1、socket也称“套接字”
2、是一种文件描述符,代表了一个通信管道的一个端点
3、类似对文件的操作一样,可以使用read、write、close等函数对socket套接字进行网络数据的收取和发送等操作
4、得到socket套接字(描述符)的方法调用socket()

2.2.3 UDP编程C/S架构

2.3 UDP编程-创建套接字

2.3.1创建socket套接字

int socket(int family,int type,int protocol);
功能:
创建一个用于网络通信的socket套接字(描述符)
参数:
family:协议族(AF_INET、AF_INET6、PF_PACKET等)
type:套接字类(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)
protocol:协议类别(0、IPPROTO_TCP、IPPROTO_UDP等

返回值:
套接字
特点:
创建套接字时,系统不会分配端口
创建的套接字默认属性是主动的,即主动发起服务的请求;当作为服务器时,往往需要修改为被动的
头文件:
#include <sys/socket.h>

2.3.2创建UDP套接字demo

int sockfd = 0;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd < 0)

perror(“socket”);
exit(-1);

注意:
AF_INET:IPv4协议
SOCK_DGRAM:数据报套接字
0:选择所给定的family和type组合的系统默认值

2.4 UDP编程-发送、绑定、接收数据

2.4.1 IPv4套接字地址结构

头文件:#include <netinet/in.h>
struct in_addr

in_addr_t s_addr;//4字节
;
struct sockaddr_in

sa_family_t sin_family;//2字节
in_port_t sin_port;//2字节
struct in_addr sin_addr;//4字节
char sin_zero[8]//8字节
;
为了使不同格式地址能被传入套接字函数,地址须要强制转换成通用套接字地址结构
头文件:#include <netinet/in.h>
struct sockaddr

sa_family_t sa_family; // 2字节
char sa_data[14] //14字节
;

注意:
以上3个结构在linux系统中已经定义

2.4.3两种地址结构使用场合

在定义源地址和目的地址结构的时候,选用struct sockaddr_in;
例:
struct sockaddr_in my_addr;

当调用编程接口函数,且该函数需要传入地址结构时需要用struct sockaddr进行强制转换
例:
bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr));

2.4.4发送数据—sendto函数

ssize_t sendto(int sockfd,const void *buf,
size_t nbytes,int flags,
const struct sockaddr *to,
socklen_t addrlen);
功能:
向to结构体指针中指定的ip,发送UDP数据
参数:
sockfd:套接字
buf: 发送数据缓冲区
nbytes: 发送数据缓冲区的大小

flags:一般为0
to: 指向目的主机地址结构体的指针
addrlen:to所指向内容的长度
注意:
通过to和addrlen确定目的地址
可以发送0长度的UDP数据包
返回值:
成功:发送数据的字符数
失败: -1

2.4.5向“网络调试助手”发送消息


例:udp_send.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc,char *argv[])

unsigned short port = 8080;
char *server_ip = “10.0.31.245”;
if(argc > 1)//通过main函数传参,传入ip地址

server_ip = argv[1];

if(argc > 2)//通过main函数传参,传入端口号

port = atoi(argv[2]);

/*创建UDP套接字*/
int sockfd;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd < 0)

	perror("socket");
	exit(-1);


/*填充目的server socket地址*/
struct sockaddr_in dest_addr;
bzero(&dest_addr,sizeof(dest_addr));
dest_addr.sin_family = AF_INET;//目的套接字地址的协议家族赋值
dest_addr.sin_port = htons(port);//目的套接字地址的端口号赋值
inet_pton(AF_INET,server_ip,&dest_addr.sin_addr);//目的套接字地址的ip地址赋值

printf("send data to UDP server %s:%d!\\n",server_ip,port);

/*发送数据到目的server*/
while(1)

	char send_buf[512];
	fgets(send_buf,sizeof(send_buf),stdin);
	send_buf[strlen(send_buf)-1] = '\\0';//字符串最后一个'\\n'变成'\\0'
	sendto(sockfd,send_buf,strlen(send_buf),0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));

close(sockfd);
return 0;

2.4.6绑定 bind函数

UDP网络程序想要收取数据需什么条件?
确定的ip地址
确定的port
怎样完成上面的条件呢?
接收端 使用bind函数,来完成地址结构与socket套接字的绑定,这样ip、port就固定了
发送端 在sendto函数中指定接收端的ip、port,就可以发送数据了

int bind(int sockfd,
const struct sockaddr *myaddr,socklen_t addrlen);
功能:
将本地协议地址与sockfd绑定
参数:
sockfd: socket套接字
myaddr: 指向特定协议的地址结构指针
addrlen:该地址结构的长度
返回值:
成功:返回0
失败:其他

2.4.7 bind示例

注意:
INADDR_ANY 通配地址,值为0
头文件:
#include <sys/socket.h>

2.4.8接收数据—recvfrom 函数

ssize_t recvfrom(int sockfd, void *buf,
size_t nbytes,int flags,
struct sockaddr *from,
socklen_t *addrlen);
功能:
接收UDP数据,并将源地址信息保存在from指向的结构中
参数:
sockfd: 套接字
buf:接收数据缓冲区
nbytes:接收数据缓冲区的大小
flags: 套接字标志(常为0)
from: 源地址结构体指针,用来保存数据的来源
addrlen: from所指内容的长度
注意:
通过from和addrlen参数存放数据来源信息
from和addrlen可以为NULL, 表示不保存数据来源
返回值:
成功:接收到的字符数
失败: -1

2.4.9接收“网络调试助手”的数据




2.5 UDP编程-client、server

想一想:
上节中的2个demo中发送数据端其实就是client;接收数据端就是server,那么client能否接收数据?server能否发送数据呢?
答:
其实在网络编程开发中client和server双方既可以有发送数据还可以接收数据;一般认为提供服务的一方为server;而接受服务的另一方为client

2.5.1 C/S架构回顾

2.5.2 UDP客户端注意点

1、本地IP、本地端口(我是谁)
2、目的IP、目的端口(发给谁)
3、在客户端的代码中,我们只设置了目的IP、目的端口

客户端的本地ip、本地port是我们调用sendto的时候linux系统底层自动给客户端分配的;分配端口的方式为随机分配,即每次运行系统给的port不一样

2.5.3 UDP服务器注意点

1、服务器之所以要bind是因为它的本地port需要是固定,而不是随机的
2、服务器也可以主动地给客户端发送数据
3、客户端也可以用bind,这样客户端的本地端口就是固定的了,但一般不这样做

第三章:UDP编程-TFTP、广播、多播

3.1 TFTP简介、通信过程

3.1.1 TFTP概述

TFTP:简单文件传送协议
最初用于引导无盘系统,被设计用来传输小文件
特点:
基于UDP协议实现
不进行用户有效性认证
数据传输模式:
octet:二进制模式
netascii:文本模式
mail:已经不再支持

3.1.2 TFTP通信过程

TFTP通信过程总结(无选项)
1、服务器在69号端口等待客户端的请求
2、服务器若批准此请求,则使用临时端口与客户端进行通信
3、每个数据包的编号都有变化(从1开始)
4、每个数据包都要得到ACK的确认如果出现超时,则需要重新发送最后的包(数据或ACK)
5、数据的长度以512Byte传输
6、小于512Byte的数据意味着传输结束
想一想
TFTP协议的格式是什么样子?

3.2 TFTP协议分析

注意:
以上的0代表的是’\\0’
不同的差错码对应不同的错误信息

错误码:
0 未定义,参见错误信息
1 File not found.
2 Access violation.
3 Disk full or allocation exceeded.
4 illegal TFTP operation.
5 Unknown transfer ID.
6 File already exists.
7 No such user.
8 Unsupported option(s) requested.

想一想
传输的数据的大小一定是512Byte吗?
由于网络的原因,一方收不到另一方的数据怎么办?

TFTP带选项
读写请求中修改了选项

如果发送带选项的读写请求

tsize选项
当读操作时,tsize选项的参数必须为“0”,服务器会返回待读取的文件的大小
当写操作时,tsize选项参数应为待写入文件的大小,服务器会回显该选项
blksize选项
修改传输文件时使用的数据块的大小(范围:8~65464)
timeout选项
修改默认的数据传输超时时间(单位:秒)


TFTP通信过程总结(带选项)
1、可以通过发送带选项的读/写请求发送给server
2、如果server允许修改选项则发送选项修改确认包
3、server发送的数据、选项修改确认包都是临时port
4、server通过timeout来对丢失数据包的重新发送

3.3练习—TFTP客户端

练习要求
使用TFTP协议,下载server上的文件到本地
实现思路
1、构造请求报文,送至服务器(69号端口)
2、等待服务器回应
3、分析服务器回应
4、接收数据,直到接收到的数据包小于规定数据长度

3.4 UDP广播

在生活中广播无处不在,像平时在大街上卖物品的商人,在进行推广产品的时候往往都是使用一个喇叭来进行“吆喝”,这就是广播。

想一想:在网络中的广播是什么样子?

广播:由一台主机向该主机所在子网内的所有主机发送数据的方式
广播只能用UDP或原始IP实现,不能用TCP

3.4.1广播的用途

单个服务器与多个客户主机通信时减少分组流通
以下几个协议都用到广播
1、地址解析协议(ARP)
2、动态主机配置协议(DHCP)
3、网络时间协议(NTP)

3.4.2 UDP广播的特点

1、处于同一子网的所有主机都必须处理数据
2、UDP数据包会沿协议栈向上一直到UDP层
3、运行音视频等较高速率工作的应用,会带来大负
4、局限于局域网内使用

3.4.3 UDP广播地址

网络ID,主机ID
网络ID表示由子网掩码中1覆盖的连续位
主机ID表示由子网掩码中0覆盖的连续位
定向广播地址:主机ID全1
1、例:对于192.168.220.0/24,其定向广播地址为192.168.220.255
2、通常路由器不转发该广播
受限广播地址:255.255.255.255
路由器从不转发该广播

3.4.4广播与单播的对比

单播:

广播:

3.4.5套接口选项

int setsockopt(int sockfd, int level,
int optname,const void *optval,
socklen_t optlen);
成功执行返回0,否则返回-1

3.4.6广播示例

3.5 UDP多播

3.5.1多播概述

多播:
数据的收发仅仅在同一分组中进行
多播的特点:
1、多播地址标示一组接口
2、多播可以用于广域网使用
3、在IPv4中,多播是可选的

3.5.2多播地址

IPv4的D类地址是多播地址
十进制:224.0.0.1  239.255.255.254
十六进制:E0.00.00.01  EF.FF.FF.FE
多播地址向以太网MAC地址的映射

3.5.3 UDP多播工作过程

3.5.4多播地址结构体

在IPv4因特网域(AF_INET)中,多播地址结构体用如下结构体ip_mreq表示

3.5.5多播套接口选项

int setsockopt(int sockfd, int level,int optname,
const void *optval, socklen_t optlen);
成功执行返回0,否则返回-1

3.5.6加入多播组示例

第四章:TCP网络编程

4.1 TCP介绍、编程流程

TCP回顾
1、面向连接的流式协议;可靠、出错重传、且每收到一个数据都要给出相应的确认
2、通信之前需要建立链接
3、服务器被动链接,客户端是主动链接
TCP与UDP的差异

TCP C/S架构

4.2 TCP编程-socket

4.2.1 TCP套接字创建

UDP套接字创建回顾

创建TCP套接字

做为客户端需要具备的条件
1、知道“服务器”的ip、port
2、主动连接“服务器”
3、需要用到的函数
socket—创建“主动TCP套接字”
connect—连接“服务器”
send—发送数据到“服务器”
recv—接受“服务器”的响应
close—关闭连接

4.3 TCP客户端-connect、send、recv

4.3.1 connect函数

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

功能:
主动跟服务器建立链接
参数:
sockfd:socket套接字
addr: 连接的服务器地址结构
len: 地址结构体长度
返回值:
成功:0 失败:其他

注意:
1、connect建立连接之后不会产生新的套接字
2、连接成功后才可以开始传输TCP数据
3、头文件:#include <sys/socket.h>

4.3.2 send函数

ssize_t send(int sockfd, const void* buf,size_t nbytes, int flags);
功能:
用于发送数据
参数:
sockfd: 已建立连接的套接字
buf: 发送数据的地址
nbytes: 发送缓数据的大小(以字节为单位)
flags: 套接字标志(常为0)
返回值:
成功发送的字节数
头文件:
#include <sys/socket.h>
注意:
不能用TCP协议发送0长度的数据包

发送数据如图所示


4.3.3 recv函数

ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
功能:
用于接收网络数据
参数:
sockfd:套接字
buf: 接收网络数据的缓冲区的地址
nbytes: 接收缓冲区的大小(以字节为单位)
flags: 套接字标志(常为0)
返回值:
成功接收到字节数
头文件:
#include <sys/socket.h>

接收数据如图所示:

4.3.4客户端code


4.4 TCP服务器-bind、listen、accept

4.4.1做为TCP服务器需要具备的条件

1、具备一个可以确知的地址
2、让操作系统知道是一个服务器,而不是客户端
3、等待连接的到来
对于面向连接的TCP协议来说,连接的建立才真正意味着数据通信的开始

4.4.2 bind示例

4.4.3 listen 函数

int listen(int sockfd, int backlog);
功能:
将套接字由主动修改为被动
使操作系统为该套接字设置一个连接队列,用来记录所有连接到该套接字的连接
参数:
sockfd: socket监听套接字
backlog:连接队列的长度
返回值:
成功:返回0
失败:其他
头文件:
#include <sys/socket.h>

4.4.4 accept函数

int accept(int sockfd,struct sockaddr *cliaddr, socklen_t *addrlen);
功能:
从已连接队列中取出一个已经建立的连接,如果没有任何连接可用,则进入睡眠等待(阻塞)
参数:
sockfd: socket监听套接字
cliaddr: 用于存放客户端套接字地址结构
addrlen:套接字地址结构体长度的地址
返回值:
已连接套接字
头文件:
#include <sys/socket.h>
注意:
返回的是一个已连接套接字,这个套接字代表当前这个连接

4.4.5 TCP服务器例子

4.5 TCP编程-close、三次握手、四次挥手

4.5.1 close 关闭套接字

1、使用close函数即可关闭套接字
关闭一个代表已连接套接字将导致另一端接收到一个0长度的数据包
2、做服务器时
1>关闭监听套接字将导致服务器无法接收新的连接,但不会影响已经建立的连接
2>关闭accept返回的已连接套接字将导致它所代表的连接被关闭,但不会影响服务器的监听
3、做客户端时
关闭连接就是关闭连接,不意味着其他

4.5.2三次握手

4.5.3四次挥手

4.6 TCP并发服务器

4.6.1多进程实现并发

4.6.2多线程实现并发

4.7 Web服务器介绍

4.7.1 web服务器简介

Web服务器又称WWW服务器、网站服务

以上是关于Linux网络编程——千峰物联网笔记的主要内容,如果未能解决你的问题,请参考以下文章

千峰HTML5+CSS3学习笔记

千峰HTML5+CSS3学习笔记

想找一个linux培训机构,目前看千峰黑马达内 北大青鸟等机构,个人一些看法

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

千峰逆战技术分享第一天 nginx错误日志文件Error.log常见错误详细说明

我想转行IT,想找一个培训机构,目前看了优就业千峰叩丁狼黑马达内等机构,请问哪个好一点?