网络编程
用于不同主机间的通信;
(1)应用层:
(2)表示层:加密解密
(3)会话层:网络断开,连接状态
(4)传输层:tcp:传输控制协议可靠通信;udp:用户数据报协议,不可靠通信
(5)网络层:ip地址
(6)链路层:网络设备、交换机
(7)物理层:硬件设备
应用层:为网络用户提供各种服务,例如电子邮件、文件传输等。
表示层:为不同主机间的通信提供统一的数据表示形式。
会话层:负责信息传输的组织和协调,管理进程会话过程。传输层:管理网络通信两端的数据传输,提供可靠或不可靠的传输服务。
网络层:负责数据传输的路由选择和网际互连。
数据链路层:负责物理相邻(通过网络介质相连)的主机间的数据传输,主要作用包括物理地址寻址、数据帧封装、差错控制等。该层可分为逻辑链路控制子层(LLC)和介质访问控制子层(MAC)。
物理层,负责把主机中的数据转换成电信号,再通过网络介质(双绞线、光纤、无线信道等)来传输。该层描述了通信设备的机械、电气、功能等特性。
应用层 ====》应用程序
传输层 ====》端口号tcp udp
网络层 ====》IP 地址
接口层 ====》网卡 驱动 1GB
TCP/IP协议族:
www.taobao.com(称为域名) ---> 192.168.0.19
www.voa.com
dns 域名解析
DHCP(动态主机配置协议)
应用层: HTTP TFTP(简单文件传输,局域网范围) FTP(互联网文件传输) SNMP DNS ...
传输层: TCP(传输控制协议) UDP(用户数据报协议) 56k猫
网络层: IP(互联网协议) ICMP(互联网控制管理协议网络检测诊断)(ping) RIPOSPF IGMP ...
物理层: ARP(地址解析协议) RARP ... ip--->mac
arp,,,,
1、IP地址的分类
网络基础 ===》A B C D E 类
010 3333344444
IP地址 == 网络位 + 主机位
IP地址的分类: 点分十进制 ipv4 712934
A类: 超大规模性网络
1.0.0.0 - 126.255.255.255 126.1.1.1
126.1.1.2
255.0.0.0
私有:
10.0.0.0 - 10.255.255.255
127.0.0.1
B类: 大中规模型网络(前两位为网络号,后面分给主机)
128.0.0.0 - 191.255.255.255
128.2.1.2 128.2.7.2
255.255.0.0
私有:
172.16.0.0 - 172.31.255.255
C类: 中小规模型网络(局域网,前三组代表网络号,后一组分给主机)
192.0.0.0 - 223.255.255.255
255.255.255.0
私有:
192.168.0.0 - 192.168.255.255
静态路由
192.168.0.0
192.168.0.1 网关
192.168.0.255C 类网络:
ip地址的前三组是网络地址,第四组是主机地址。
二进制的最高位必须是: 110xxxxx开头
十进制表示范围: 192.0.0.0 -223.255.255.255
默认网络掩码: 255.255.255.0
网络个数: 2^24 个 约 209 万个
主机个数: 2^8 个 254 个+2 ===》1 是网关 1是广播
私有地址: 192.168.x.x 局域网地址。
D类: 组播和广播
224.0.0.0 - 239.255.255.255
192.168.0.255 == 255.255.255.255
235.1.2.3
192.168.1.0
192.168.0.1 网关
192.168.1.255 广播
E类: 实验
240.0.0.0 - 255.255.255.255
2、网络配置
sudo vim /etc/network/interfaces //网络配置
//接口
auto ens33启动网络设备
iface ens33 inet dhcp自动获取ip地址
sudo /etc/init.d/networking restart //网络重置命令
sudo reboot //重启
3、单机上网的配置:
1、有网络接口并插入网线。
2、有ip地址
3、配置网络设置ip: ifconfig ethX X.X.X.X/24 up ifconfig ens33 192.168.0.13/24 up 255.255.255.0
查询本机IP //设置IP地址,临时性,重启就没有了
网关: route add default gw x.x.x.x
DNS: vi /etc/resolv.conf ==>nameserver 8.8.8.8
测试:ping www.baidu.com //检查能否上网netstat -anp //网络状态/
1、socket 套接字(第一种表示:网络设备对应的文件描述符) ==》BSD socket ==》(第二种表示)用于网络通信的一组接口函数。socket api application interface
2、ip+port 地址+端口===》地址用来识别主机
端口用来识别应用程序:用于找进程port分为TCP port / UDP port 范围都是: 1-65535
约定1000 以内的端口为系统使用。
http 80 www.baidu.com
3306
telnet 21
ssh 22
网络字节序 ===》大端存储 主机字节序
12 00 小端 0x12345678
00 12
192.168.0.12
12.0.168.192
udp的特征
服务端:提供网络服务
客户端:使用网络服务
在网络程序,是客户端找服务器,服务器不能找客户端,故服务端需使用bind来绑定端口号;
1、socket函数:
#include
/* See NOTES */
#include形式:
int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符参数:domain 地址族,PF_INET == AF_INET ==>互联网程序
PF_UNIX == AF_UNIX ==>单机程序
type 套接字类型:
SOCK_STREAM 流式套接字 ===》TCP
SOCK_DGRAM 用户数据报套接字===>UDP
SOCK_RAW 原始套接字 ===》IP
protocol 协议 ==》0 表示自动适应应用层协议。(前面已经描述清楚,TCP\UDP都填0)返回值:成功 返回申请的套接字id, 失败 -1;
int bind(int sockfd, struct sockaddr *my_addr,
socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关的文件描述符文件与参数2 指定的接口地址关联, 用于从该接口接受数据。如果该函数在客户端调用,则表示要将数据从参数1所在的描述符中取出并从参数2所在的接口设备上发送出去。
注意:如果是客户端,则该函数可以省略,由默认接口发送数据。
参数:sockfd 之前通过socket函数创建的文件描述符,套接字id
my_addr 是物理接口的结构体指针。表示该接口的信息。struct sockaddr 通用地址结构
{
u_short sa_family; 地址族
char sa_data[14]; 地址信息
};转换成网络地址结构如下:
struct _sockaddr_in ///网络地址结构
{
u_short sin_family; 地址族
u_short sin_port; ///地址端口,一般建议值大于50000,使用htons(host to net short),进行地址转换(将一个无符号短整型数值转换为网络字节序,即大端模式)
struct in_addr sin_addr; ///地址IP,使用函数inet_addr(192.168.116.130);将字符串(小端)转为大端
char sin_zero[8]; 占位
};struct in_addr
{
in_addr_t s_addr;
}socklen_t addrlen: 参数2 的长度。
返回值:成功 0,失败 -1;
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
收到buf 大小 一般默认为0 ,无人发送时阻塞
struct sockaddr *src_addr, socklen_t *addrlen);
对方地址 大小:int len = sizeof(cli);
&len
ssize_t sendto(int sockfd, const char *buf, size_t len, int flags,
发生buf内容
const struct sockaddr *dest_addr, socklen_t addrlen);
发给谁
1、特性: 无链接 不可靠 大数据
2、框架: C/S模式
server:socket() ===>bind()===>recvfrom()===>close()
client:socket() ===>bind()===>sendto() ===>close()
注意:socket()的参数需要调整。
socket(PF_INET,SOCK_DGRAM,0);
bind() 客户端是可选的,服务器端是比选的。
发送函数:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
功能:用于UDP协议中向对方发送数据。
参数:sockfd 本地的套接字id
buff 本地的数据存储,一般是要发送的数据。
len 要发送的数据长度
flags 要发送数据方式,0 表示阻塞发送。dest_addr: 必选,表示要发送到的目标主机信息结构体。
addrlen :目标地址长度。返回值:成功 发送的数据长度, 失败 -1;
接收函数:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);功能:用于UDP协议中获取对方发送的数据。
参数:sockfd 本地的套接字id
buff 要存储数据的内存区,一般是数组或者动态内存。
len 要获取的数据长度,一般是buff的大小。
flags 获取方式,0 阻塞src_addr 可选,表示对方的地址信息结构体,
如果为NULL,表示不关心对方地址。
addrlen 对方地址信息结构体大小。
如果对方地址是NULL,则该值也为NULL。
返回值:成功 接收到的数据长度
失败 -1;
服务端:
#include
#include
#include
#include /* See NOTES */
#include
#include
#include /* superset of previous */
#include
#include
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(-1 == sockfd)
{
perror("socket");
return 1;
}
struct sockaddr_in ser,cli;//client man 7 ip
bzero(&ser,sizeof(ser));
bzero(&cli,sizeof(cli));
ser.sin_family = AF_INET;
ser.sin_port = htons(50000); // host to net short
ser.sin_addr.s_addr = inet_addr("192.168.0.199");// 小端转大端
int ret = bind(sockfd,(SA)&ser,sizeof(ser));
if(-1 == ret)
{
perror("bind");
return 1;
}
socklen_t len = sizeof(cli);
while(1)
{
char buf[256]={0};
recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);
time_t tm;
time(&tm);
struct tm * tminfo = localtime(&tm);
sprintf(buf,"%s %d:%d:%d\n",buf,tminfo->tm_hour,tminfo->tm_min
,tminfo->tm_sec);
sendto(sockfd,buf,strlen(buf),0,(SA)&cli,sizeof(cli));
}
return 0;
}
客户端:
#include
#include
#include
#include /* See NOTES */
#include
#include
#include /* superset of previous */
#include
#include
#include
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(-1 == sockfd)
{
perror("socket");
return 1;
}
struct sockaddr_in ser,cli;//client man 7 ip
bzero(&ser,sizeof(ser));
bzero(&cli,sizeof(cli));
ser.sin_family = AF_INET;
ser.sin_port = htons(50000); // host to net short
ser.sin_addr.s_addr = inet_addr("192.168.0.161");// 小端转大端
socklen_t len = sizeof(cli);
while(1)
{
char buf[256]={0};
strcpy(buf,"this is udp test");
sendto(sockfd,buf,strlen(buf),0,(SA)&ser,sizeof(ser));
bzero(buf,sizeof(buf));
recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
printf("server:%s",buf);
sleep(1);
}
close(sockfd);
return 0;
}