一、知识点归纳以及自己最有收获的内容
1、知识点归纳
第13章 TCP/IP和网络编程
1、TCP/IP协议
TCP/IP传输协议,即传输控制/网络协议,也叫作网络通讯协议。它是在网络的使用中的最基本的通信协议。TCP/IP传输协议对互联网中各部分进行通信的标准和方法进行了规定。并且,TCP/IP传输协议是保证网络数据信息及时、完整传输的两个重要的协议。TCP/IP传输协议是严格来说是一个四层的体系结构,应用层、传输层、网络层和数据链路层都包含其中。
TCP/IP协议是Internet最基本的协议,其中应用层的主要协议有Telnet、FTP、SMTP等,是用来接收来自传输层的数据或者按不同应用要求与方式将数据传输至传输层;传输层的主要协议有UDP、TCP,是使用者使用平台和计算机信息网内部数据结合的通道,可以实现数据传输与数据共享;网络层的主要协议有ICMP、IP、IGMP,主要负责网络中数据包的传送等;而网络访问层,也叫网路接口层或数据链路层,主要协议有ARP、RARP,主要功能是提供链路管理错误检测、对不同通信媒介有关信息细节问题进行有效处理等。
2、IP主机和IP地址
- IP主机
主机是支持TCP/IP协议的计算机或设备。
每个主机由一个32位的IP地址来标识。为方便起见,32位的IP地址号通常用点记法(点分十进制)表示,例如:134.121.64.1,其中各个字节用点号分开。主机也可以用主机名来表示,如dns1.eec.wsu.edu。 - IP地址
分为两部分,即NetworkID字段和HostID字段。根据划分,IP地址分为A~E类。例如,一个B类P地址被划分为一个16位NetworkID,其中前2位是10,然后是一个16位的HostID字段。发往P地址的数据包首先被发送到具有相同networkID 的路由器。路由器将通过HostID将数据包转发到网络中的特定主机。每个主机都有一个本地主机名localhost,默认P地址为127.0.0.1。本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个 localhost。
3、IP协议
用于在IP主机之间发送/接收数据包。IP尽最大努力运行。IP主机只向接收主机发送数据包,但它不能保证数据包会被发送到它们的目的地,也不能保证按顺序发送。
- IP数据包由IP头、发送方地址和接收方IP地址以及数据组成。
4、UDP/TCP
-
UDP(用户数据报协议)
在IP上运行,用于发送/接收数据报。与IP类似,UDP不能保证可靠性,但是快速高效。它可用于可靠性不重要的情况。 -
TCP(传输控制协议)
是一种面向连接的协议,用于发送/接收数据流。TCP也可在IP 上运行,但它保证了可靠的数据传输。通常,UDP类似于发送邮件的USPS,而TCP类似于电话连接。
5、套接字API
在网络编程中,TCP/IP的用户界面是通过一系列C语言库函数和系统调用来实现的,这些函数和系统调用统称为套接字API((Rago1993;Stevens等2004)。为了使用套接字 API,我们需要套接字地址结构,它用于标识服务器和客户机。netdbh和sys/socketh中有套接字地址结构的定义。
- 套接字地址
struct sockaddr_in {
sa_family_t sin_family; // AF_INET for TCP/IP
in port_t sinport; // port number
struct in_addr sin_addr; // IP address
};
struct in_addr{ //internet address
uint32_t s_addr; // IP address in network byte order
};
在套接字地址结构中
TCP/IP网络的sin family始终设置为AFINET。
sin_port包含按网络字节顺序排列的端口号。
sin_addr是按网络字节顺序排列的主机IP地址。
- 套接字API
- int套接字 (int域 ,int类型,int协议)
- int bind(int sockfd,struct sockaddr *addr,socklen_t addrlen)
- UDP套接字
UDP套接字使用sendto()/recvfrom0)来发送/接收数据报。
ssizetsendto(int sockfd, const void *buf, sizet len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssizet recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklent *addrlen);
- TCP套接字
在创建套接字并将其绑定到服务器地址之后,TCP服务器使用listen()和accept()来接收来自客户机的连接
int listen(int sockfdint backlog);
int accept(int sockfd,struct sockaddr *addr,socklen t *addrlen);
6、字节排序函数
小端和大端(内存中存储两个字节有两种方法)
小端(little-endian):将低序字节存储在起始地址
大端(big-endian):将高序字节存储在起始地址
主机字节序:某个给定系统所用的字节序
输出字节序的程序:
#iclude"unp.h"
int main(int argc,char **argv)
{
union{
short s;
char c[sizeof(short)];
}un;
un.s=0x0102;
printf("%s:",CUP_VENDOR_OS);
if(sizeof(short)==2){
if(un.c[0]==1&&un.c[1]==2)
printf("big-endian\n");
else if (un.c[0]==2&&un.c[1]==1)
printf("little-endian\n");
else
printf("unknown\n");
}else
printf("sizeof(short)=%d\n",sizeof(short));
exit(0);
}
7、字节操纵函数
bzero:bzero把目标字节串指定数目的字节置为0。我们常用该函数把一个套接字地址结构初始化为0.
bocpy:指定数目的字节从源字节串移动到目标字节串。
bcmp:比较两个任意的字节串,若相同返回值为0,否则返回值为非0.
memset:把目标字节串指定数目的字节置为c。
mencmp:比较两个任意的字符串,若相同为0,否则返回一个非0值,是大于0还是小于0则取决于第一个不等的字节。
支持IPv4的inet_pton函数的简单定义:
int inet_pton(int family,const char *strptr,void *addrptr)
{
if(family==AF_INET)
{
struct in_addr in_val;
if(inet_aton(strptr,&in_val))
{
memcpy(addrptr,&in_val,sizeof(struct int_addr));
return(1);
}
return(0);
}
errno=EAFNOSUPPROT;
return(-1);
}
二、实践内容与截图
实践1:socket编程并将信息加密
Client.c
Server.c
运行结果:
Server:
Client:
client用AES将信息加密后发送
server用AES将解密后收取
同理server端可以发送信息client接收