知识点归纳

第十三章 TCP/IP和网络编程

学习目标

通过本章的学习,了解TCP/IP协议及其应用,包括TCP/IP协议栈,ip地址,主机名,DNS,IP数据包和路由器;理解TCP/IP协议簇中的UDP和TCP协议、端口号和数据流;理解套接字,并通过简单编程来加深理解。第二部分介绍web和CGI编程,解释HTTPD服务器,及HTTP编程模型,理解web服务器的配置和运行。

网络编程

1.什么是网络、计算机网络的构成是什么?

在计算领域中,网络是传输信息、接受、共享的虚拟的平台。
通过它可以把各个点、面、体的信息联系到一起,从而实现这些资源的共享。
网络是人类发展史上最重要的发明,提高了人类和科技的一个发展。

2.什么是网络编程?

网络编程从大的方面就是说对信息的发送接收。
通过操作相应API调度计算机资源硬件,并且利用管道(网线)进行数据交互的过程。
更为具体的涉及:网络模型、套接字、数据包。

3.7层网络模型–OSI

基础层:物理层(physical)、数据链路层(Datalink)、网络层(network).。
传输层(Transport):TCP-UDP协议层、Socket。
高级层::会话层(Session)、表示层(Presentation)、应用层(Application)

4.网络模型—对应关系

5.Socket与TCP、UDP

Socket:

简单来说是ip地址与端口的结合协议(RFC 793).
一种地址与端口的结合描述协议。
TCP/IP协议的相关API的总称;是网络API的集合实现.
涵盖了Stream socket /Datagram Socket

socket 的组成与作用:

在网络传输中用于唯一标识两个端点的链接。
端点:包括(ip+port)
4个要素:客户端的地址、客户端的端口、服务器的地址、服务器端口。

TCP/IP协议

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
TCP/IP(Comer 1988,2001;RFC1180 1991)是互联网的基础。TCP代表传输控制协议。IP 代表互联网协议。目前有两个版本的IP,即IPv4和IPv6。IPv4使用32位地址,IPv6则使用128位地址。

如图所示为 TCP/IP 的各个层级以及每一层级的代表性组件及其功能。


翻译过来就是

TCP/IP 网络中的数据流路径。

IP主机和IP地址

每个主机都有一个本地主机名localhost,默认 IP地址为 127.0.0.1。
本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个localhost。这个特性可以让我们在同一台计算机上运行TCP/IP 应用程序,而不需要实际连接到互联网。
IP地址分为两部分,即 NetworkID 字段和HostID字段。根据划分,IP 地址分为A~E类。

类别 最大网络数 IP地址范围 单个网段最大主机数 私有IP地址范围
A 126(2^7-2) 1.0.0.1-127.255.255.254 16777214 10.0.0.0-10.255.255.255
B 16384(2^14) 128.0.0.1-191.255.255.254 65534 172.16.0.0-172.31.255.255
C 2097152(2^21) 192.0.0.1-223.255.255.254 254 192.168.0.0-192.168.255.255

IP协议

IP协议用于在 IP主机之间发送/接收数据包。IP尽最大努力运行。IP 主机只向接收主机发送数据包,但它不能保证数据包会被发送到它们的目的地,也不能保证按顺序发送。这意味着IP 并非可靠的协议。

IP报头格式

路由器

是接收和转发数据包的特殊IP主机。一个IP数据包可能会经过许多路由器,或者跳跃到达某个目的地。每个IP包在IP报头中都有一个8位生存时间(TTL)计数,其最大值为255。

UDP

UDP(用户数据报协议)(RFC768 1980;Comer 1988)在IP上运行,用于发送/接收数据报。与IP类似,UDP不能保证可靠性,但是快速高效。

TCP

TCP(传输控制协议)是一种面向连接的协议,用于发送/接收数据流。TCP也可在IP 上运行,但它保证了可靠的数据传输。

端口编号

端口号是分配给应用程序的唯一无符号短整数。要想使用UDP或TCP,应用程序(进程)必须先选择或获取一个端口号。前1024个端口号已被预留。其他端口号可供一般使用。应用程序可以选择一个可用端口号,也可以让操作系统内核分配端口号。
端口号的范围从0到65535。

TCP/IP中的数据流

应用程序层的数据被传递到传输层,传输层给数据添加一个TCP或UDP 报头来标识使用的传输协议。合并后的数据被传递到IP 网络层,添加一个包含 IP地址的IP 报头来标识发送和接收主机。然后,合并后的数据再被传递到网络链路层,网络链路层将数据分成多个帧,并添加发送和接收网络的地址,用于在物理网络之间传输。IP地址到网络地址的映射由地址解析协议(ARP)执行(ARP1982)。在接收端,数据编码过程是相反的。每一层通过剥离数据头来解包接收到的数据、重新组装数据并将数据传递到上一层。发送主机上的应用程序原始数据最终会被传递到接收主机上的相应应用程序。

实践代码、截图

使用C语言实现简单UDP传输

客户端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#define MAXBUF 256
int main(int argc, char const *argv[])
{
	int s = 0;
	int n = 0;
	int reuse = 1;
	int port = 1987;
	struct sockaddr_in srv;
	char buf[MAXBUF] = {0};
	/*解析参数*/
	if (argc != 2)
	{
		printf("Usage:%s ServerIP\n", argv[0]);
		return -1;
	}
 
	bzero(&srv, sizeof(srv));
	srv.sin_family = PF_INET;
	srv.sin_addr.s_addr = inet_addr(argv[1]);
	srv.sin_port = htons(port);
	/*创建 UDP 套节字*/
	s = socket(AF_INET, SOCK_DGRAM, 0);
	if(s<0){
		perror("socket");
		return -1;
	}
 
	while(1){
		memset(buf, 0, MAXBUF);
		/*读取用户输入到buf中*/
		fgets(buf, MAXBUF, stdin);
 
		/*通过套节字 s 向服务器发送数据*/
		if ((n = sendto(s, buf, strlen(buf), 0, (struct sockaddr *) &srv, sizeof(struct sockaddr))) < 0)
		{
			perror("sendto");
			return -1;
		}else{
			printf("send to %s(port=%d) len %d:%s\n", argv[1], port, n, buf);
		}
	}
}

服务端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
 
#define MAXBUF 256
int main(int argc, char const *argv[])
{
	int s = 0;
	int n = 0;
	int reuse = 1;
	int cli_len = sizeof(struct sockaddr);
	int port = 1987;
	char buf[MAXBUF] = {0};
	struct sockaddr_in addr, cli;
 
	/*初始化本地监听端口信息*/
	bzero(&addr, sizeof(addr));
	addr.sin_family = PF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);
 
	/*创建UDP套节字*/
	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s<0)
	{
		perror("socket");
		return -1;
	}
 
	/*允许端口复用*/
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
 
	/*绑定指定端口*/
	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		perror("bind");
		return -1;
	}
 
	while(1){
		memset(buf, 0, MAXBUF);
		/*从套节字s中读取数据*/
		n = recvfrom(s, buf, MAXBUF, 0, (struct sockaddr *)&cli, &cli_len);
		if(n<0){
			perror("recvfrom");
			return -1;
		}else{
			printf("receive msg from %s(port=%d) len %d: %s\n",inet_ntoa(cli.sin_addr), port, n, buf);
		}
	}
	
	return 0;
}

运行截图

编译

运行

参考,特别感谢

https://www.cnblogs.com/DKYcaiji/p/15600552.html
https://blog.csdn.net/qq_38616723/article/details/85345567

原文地址:http://www.cnblogs.com/wulongcan20201306/p/16879919.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性