一 TCP/IP协议概述
1 OSI参考模型与TCP/IP参考模型
OSI参考模型:应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。
TCP/IP参考模型:
应用层:负责应用程序的网络访问,这里通过端口号来识别不同的进程。
http ftp
传输层:负责端对端之间的通信会话连接与建立,传输协议的选择根据数据传输方式而定。
tcp udp
网络层:负责将数据侦封装成IP数据报,并运行必要的路由算法。
icmp igmp ipv4 ipv6
网络接口层:负责将二进制流转换为数据侦,并进行数据侦的发送和接收,要注意的是数据振是独立的网络信息传输单元。
arp rarp mpls
ARP:用于获得同一物理网络中的硬件主机地址
MPLS:多协议标签协议
IP:负责在主机和网络之间寻址和路由数据包
ICMP:用于发送报告有关数据包的传送错误的协议
IGMP:被IP主机用来向本地多路广播路由器报告主机组成员的协议
TCP:为应用程序提供可靠的通信连接,适合一次传输大连数据的情况,并适用于要求得到相应的应用程序。
UDP:提供了无连接通信,且不对传送包进行可靠的保证。适合一次传输少量数据。
TCP实体所采用的基本协议是滑动窗口协议。
UDP 用户数据报协议,无连接嫌疑。
协议的选择
a 对数据可靠性的要求
验证、密码字段的传送使用TCP
对数据的可靠性要求不高的应用可以选择UDP
b 应用的实时性
TCP协议在传送过程中要进行三次握手,使用TCP协议会有较大的时间延迟。
c 网络的可靠性
广域网用TCP
局域网用UDP
二 网络编程基础
1 socket
每一个socket都用一个半相关描述[协议,本地地址,本地端口]
一个完整的套接字则用一个相关描述[协议,本地地址,本地端口,远程地址,远程端口]
2 socket类型
a 流式socket(SOCK_STREAM)
提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性
b 数据报socket SOCK_DGRAM
定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠的、无差错的,使用UDP
c 原始socket
主要用于协议的开发
二 地址及顺序处理
1 地址结构相关处理
struct sockaddr{
unsigned short sa_family;//地址族
char sa_data[14];//14字节的协议地址,包含该socket的IP地址和端口号。
}
struct sockaddr_in{
short sa_family;
unsigned short sin_port;端口号
struct in_add sin_addr;IP地址
unsigned char sin_zero[8];填充0
}
sa_family:
AF_INET:IPv4协议
AF_INET6:IPv6协议
AF_LOCAL:UNIX域协议
AF_LINK:链路地址协议
AF_KEY:密钥套接字
2 数据存储优先顺序
Internet上数据以高字节优先顺序在网络上传输
htons,ntohs,htonl,ntohl
h:host
n:network
s:short
l:long
#include<netinet/in.h>
uint16_t htons(unit16_t host16bit);
uint32_t htonl(unit32_t host32bit);
uint16_t ntohs(unit16_t net16bit);
uint32_t ntohl(unit32_t net32bit);
host16bit:主机字节序的16bit数据
host32bit:主机字节序的32bit数据
函数返回值:成功返回要转换的字节序,出错返回-1
3 地址格式转化
inet_aton,inet_addr inet_ntoa
inet_pton inet_netop
inet_pton:将点分十进制映射为二进制地址
inet_netop:将二进制地址映射为点分十进制地址
#include <arpa/inet.h>
int inet_pton(int family,const char *src,void *dst)
family:
AF_INET:ipv4
AF_INET6:ipv6
src:要转化的值
dst:转化后的值
转化字符串src到网络地址结构,然后将网络地址复制到dst。
in_addr ipv4
in6_addr ipv6
const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);
#include <arpa/inet.h>
char IPdotdec[20]; //存放点分十进制IP地址
struct in_addr s; // IPv4地址结构体
int main (void)
{
// 输入IP地址
printf("Please input IP address: ");
scanf("%s",IPdotdec);
// 转换
inet_pton(AF_INET, IPdotdec, (void *)&s);
printf("inet_pton: 0x%x\n", s.s_addr); // 注意得到的字节序
// 反转换
inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
printf("inet_ntop: %s\n", IPdotdec);
}
4 名字地址转化
gethostbyname
gehostbyadd
getaddrinfo
struct hostent{
char *h_name;正是主机名
char **h_aliases;主机别名
int h_addrtype;地址类型
int h_length;地址长度
char **h_addr_list;指向IPV4或IPV6的地址指针数组
}
struct addrinfo{
int ai_flags;AI_PASSIVE,AI_CANONNAME
int ai_family;地址族
int ai_socktype;socket类型
int ai_protocol;协议类型
size_t ai_addrlen;地址长度
char *ai_canoname;主机名
struct sockaddr *ar_addr;socket结构体
struct addrinfo *ai_next;下一个指针链表
}
#include<netdb.h>
struct hostent *gthostbyname(const char *name);
过时的函数,应该使用getaddrinfo()和getnameinfo()函数替代。
int getaddrinfo(const char *node,const char *service,const struct addrino *hints,struct addrinfo **res);
5 socket基础编程
socket:用于建立一个socket连接,可指定socket类型等信息,在建立socket连接后,可对socketadd或sockaddr_in进行初始化,以保存所建立的socket信息。
bind:将本地IP地址帮定端口号,主要用于TCP的连接
connect:用于bind之后的client端,用于与服务器建立连接
send和recv:用于接收和发送数据,可以用于TCP,UDP,当用于UDP时,应在connect建立之后再用。
sendto和recefrom,在TCP中,后面的几个与地址有关的参数不起作用,函数等同于send和recv。在UDP中,可以用在之前没有使用connect的情况下,这两个函数可以自动寻找制定地址并进行连接。
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
domain:
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)
int bind(int socket,const struct sockaddr *address,socklen_t address_len);
socktd:套接字描述符
address:本地地址
addrlen:地址长度
1 OSI参考模型与TCP/IP参考模型
OSI参考模型:应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。
TCP/IP参考模型:
应用层:负责应用程序的网络访问,这里通过端口号来识别不同的进程。
http ftp
传输层:负责端对端之间的通信会话连接与建立,传输协议的选择根据数据传输方式而定。
tcp udp
网络层:负责将数据侦封装成IP数据报,并运行必要的路由算法。
icmp igmp ipv4 ipv6
网络接口层:负责将二进制流转换为数据侦,并进行数据侦的发送和接收,要注意的是数据振是独立的网络信息传输单元。
arp rarp mpls
ARP:用于获得同一物理网络中的硬件主机地址
MPLS:多协议标签协议
IP:负责在主机和网络之间寻址和路由数据包
ICMP:用于发送报告有关数据包的传送错误的协议
IGMP:被IP主机用来向本地多路广播路由器报告主机组成员的协议
TCP:为应用程序提供可靠的通信连接,适合一次传输大连数据的情况,并适用于要求得到相应的应用程序。
UDP:提供了无连接通信,且不对传送包进行可靠的保证。适合一次传输少量数据。
TCP实体所采用的基本协议是滑动窗口协议。
UDP 用户数据报协议,无连接嫌疑。
协议的选择
a 对数据可靠性的要求
验证、密码字段的传送使用TCP
对数据的可靠性要求不高的应用可以选择UDP
b 应用的实时性
TCP协议在传送过程中要进行三次握手,使用TCP协议会有较大的时间延迟。
c 网络的可靠性
广域网用TCP
局域网用UDP
二 网络编程基础
1 socket
每一个socket都用一个半相关描述[协议,本地地址,本地端口]
一个完整的套接字则用一个相关描述[协议,本地地址,本地端口,远程地址,远程端口]
2 socket类型
a 流式socket(SOCK_STREAM)
提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性
b 数据报socket SOCK_DGRAM
定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠的、无差错的,使用UDP
c 原始socket
主要用于协议的开发
二 地址及顺序处理
1 地址结构相关处理
struct sockaddr{
unsigned short sa_family;//地址族
char sa_data[14];//14字节的协议地址,包含该socket的IP地址和端口号。
}
struct sockaddr_in{
short sa_family;
unsigned short sin_port;端口号
struct in_add sin_addr;IP地址
unsigned char sin_zero[8];填充0
}
sa_family:
AF_INET:IPv4协议
AF_INET6:IPv6协议
AF_LOCAL:UNIX域协议
AF_LINK:链路地址协议
AF_KEY:密钥套接字
2 数据存储优先顺序
Internet上数据以高字节优先顺序在网络上传输
htons,ntohs,htonl,ntohl
h:host
n:network
s:short
l:long
#include<netinet/in.h>
uint16_t htons(unit16_t host16bit);
uint32_t htonl(unit32_t host32bit);
uint16_t ntohs(unit16_t net16bit);
uint32_t ntohl(unit32_t net32bit);
host16bit:主机字节序的16bit数据
host32bit:主机字节序的32bit数据
函数返回值:成功返回要转换的字节序,出错返回-1
3 地址格式转化
inet_aton,inet_addr inet_ntoa
inet_pton inet_netop
inet_pton:将点分十进制映射为二进制地址
inet_netop:将二进制地址映射为点分十进制地址
#include <arpa/inet.h>
int inet_pton(int family,const char *src,void *dst)
family:
AF_INET:ipv4
AF_INET6:ipv6
src:要转化的值
dst:转化后的值
转化字符串src到网络地址结构,然后将网络地址复制到dst。
in_addr ipv4
in6_addr ipv6
const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);
#include <arpa/inet.h>
char IPdotdec[20]; //存放点分十进制IP地址
struct in_addr s; // IPv4地址结构体
int main (void)
{
// 输入IP地址
printf("Please input IP address: ");
scanf("%s",IPdotdec);
// 转换
inet_pton(AF_INET, IPdotdec, (void *)&s);
printf("inet_pton: 0x%x\n", s.s_addr); // 注意得到的字节序
// 反转换
inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
printf("inet_ntop: %s\n", IPdotdec);
}
4 名字地址转化
gethostbyname
gehostbyadd
getaddrinfo
struct hostent{
char *h_name;正是主机名
char **h_aliases;主机别名
int h_addrtype;地址类型
int h_length;地址长度
char **h_addr_list;指向IPV4或IPV6的地址指针数组
}
struct addrinfo{
int ai_flags;AI_PASSIVE,AI_CANONNAME
int ai_family;地址族
int ai_socktype;socket类型
int ai_protocol;协议类型
size_t ai_addrlen;地址长度
char *ai_canoname;主机名
struct sockaddr *ar_addr;socket结构体
struct addrinfo *ai_next;下一个指针链表
}
#include<netdb.h>
struct hostent *gthostbyname(const char *name);
过时的函数,应该使用getaddrinfo()和getnameinfo()函数替代。
int getaddrinfo(const char *node,const char *service,const struct addrino *hints,struct addrinfo **res);
5 socket基础编程
socket:用于建立一个socket连接,可指定socket类型等信息,在建立socket连接后,可对socketadd或sockaddr_in进行初始化,以保存所建立的socket信息。
bind:将本地IP地址帮定端口号,主要用于TCP的连接
connect:用于bind之后的client端,用于与服务器建立连接
send和recv:用于接收和发送数据,可以用于TCP,UDP,当用于UDP时,应在connect建立之后再用。
sendto和recefrom,在TCP中,后面的几个与地址有关的参数不起作用,函数等同于send和recv。在UDP中,可以用在之前没有使用connect的情况下,这两个函数可以自动寻找制定地址并进行连接。
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
domain:
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK Appletalk ddp(7)
AF_PACKET Low level packet interface packet(7)
int bind(int socket,const struct sockaddr *address,socklen_t address_len);
socktd:套接字描述符
address:本地地址
addrlen:地址长度
posted on
浙公网安备 33010602011771号