网络以及通信

网络

网络模型有哪两类?答:OSI、 TCP/IP

OSI有哪七层?答:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

端口号的作用?答:区别不同服务

TCP建立与关闭连接分别几次握手?答:3次 4次

总结

OSI模型

七层结构简介

应用OSI 模型

 

帧规范

一种典型的Ethernet帧

一种典型的Token Ring

传输控制协议/网际协议

TCP/IP模型和OSI的比较

相同点

  1. 两者都是以协议栈的概念为基础
  2. 协议栈中的协议彼此相互独立
  3. 下层对上层提供服务

不同点

  1. OSI是先有模型; TCP/IP是先有协议,后有模型
  2. OSI适用于各种协议栈; TCP/IP只适用于TCP/IP网络
  3. 层次数量不同

 

TCP/IP核心协议

IP协议

  1. 网际协议(IP)属于TCP/IP模型和互连网层,提供关于数据应如何传输以及传输到何处的信息。
  2. IP是一种使TCP/IP可用于网络连接的子协议,即TCP/IP可跨越多个局域网段或通过路由器跨越多种类型的网络。
  3. 数据帧的I P部分被称为一个IP数据报, IP数据报如同数据的封面,包含了路由器在子网中传输数据所必需的信息。

IP数据包

传输控制协议( TCP)协议

  1. 属于TCP/IP协议群中的传输层,提供可靠的数据传输服务。
  2. TCP是一种面向连接的子协议,意味着在该协议准备发送数据时,通信节点之间必须建立起一个连接。
  3. TCP协议位于IP子协议的上层,通过提供校验和、流控制及序列信息弥补I P协议可靠性的缺陷。
  4. 另一方面, T C P包括了可保证数据可靠性的几个组件。是一种可靠的、面向连接的、字节流协议。
  5. TCP提供的可靠性是利用一种称为“重传肯定确认”机制来实现的。

TCP数据包

在传输数据之前,建立对话的两个端点之间交换称为握手的控制信息。

  1. TCP通过在段头第4个字的标志字段中设置相应的位来表示一个段的控制功能。
  2. TCP有三个段要交换,故称为“三段试握手”。
  3. 当协作双方的模块结束数据传输时,它们就利用包含“无数据发送(FIN)”位的段来交换三段试握手信息,以关闭连接。

UDP (用户数据报协议)

  1. UDP是一种无连接的传输服务,它不保证数据包以正确的序列被接收
  2. 实际上根本不保证数据包的接收,而且,它不提供错误校验或序列编号。
  3. UDP报头仅包含了四个域:源端口、目标端口、长度和校验和。

TCP和UDP的区别

  1. TCP提供一种面向连接的、可靠的字节流服务
  2. UDP是无连接的、不可靠的数据协议报

字节序(大小端)

大端字节序: 低位存在高地址, 高位存在低地址

小端字节序:  低位存在低地址, 高位存在高地址

判断字节序

static int isBigEndian()

{

uint32_t thisx = 0x01020304;

uint8_t *thisp = (uint8_t *)&thisx;

return (*thisp == 1) ? 1 : 0;

}

int main(int argc, char **argv)

{

printf("Byte order: %s Endian\n", isBigEndian() ?"Big" :"Little");

return 0;

}

网络基础知识

本机端口号和网络端口相互转换

uint16_t htons(uint16_t hostshort);//本机 ---->网络

uint16_t ntohs(uint16_t netshort); // 网络 --->本机

              //htonl为32位机

点分十进制IP 地址 和 网络地址相互转换

int inet_pton(int af, const char *src, void *dst);

函数功能: 将点分十进制地址  转成网络地址

参数说明:

af:  地址族 

IPV4:  AF_INET

IPV6:  AF_INET6

src:  ip地址内存的起始地址

dst:   存放网络地址内存的起始地址

const char *inet_ntop(int af, const void *src,

                             char *dst, socklen_t size);

函数功能:将网络地址 转成点分十进制地址 (字符串存储)

参数说明:

af:  地址族

src:  网络地址内存起始地址

dst:  存放点分十进制地址内存的起始地址

size : 内存的大小

例:inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr);

地址族结构体: 

通过该结构体打包IP和端口号

原始结构体类型(已经不使用!):

struct sockaddr

{

       sa_family_t sa_family;    /* 地址族 */

       char     sa_data[14];    /* 地址值,实际可能更长 */

};

改进后的结构体:

struct in_addr

{

       in_addr_t s_addr;

};

struct sockaddr_in

{

       uint16_t  sin_family;  //地址族  IPv4:  AF_INET

       uint16_t   sin_port;   // 网络字节序端口号

struct  in_addr sin_addr;  // 网络字节序的IP地址

       char    sin_zero[8];

};

例:struct sockaddr_in  seraddr;

       int addrlen = sizeof(struct sockaddr_in);

       seraddr.sin_family = AF_INET;

       seraddr.sin_port = htons(8001);

       inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr.s_addr);

       ret = bind(sockfd, (struct sockaddr*)&seraddr, addrlen);

TCP客户服务器编程模型

客户端通常的调用序列是:

  1. 调用socket函数创建套接字。
  2. 调用connect连接服务器端。
  3. 调用I/O函数(read/write)与服务器端通讯。
  4. 调用close关闭套接字。

服务器端通常的调用序列为:

  1. 调用socket函数创建套接字。
  2. 调用bind指定本地地址和端口。
  3. 调用listen启动监听。
  4. 调用accept从已连接列队中提取客户连接。
  5. 调用I/O函数(read/write)与客户端通讯。
  6. 调用close关闭连接

server服务器端

创建监听套接字

int socket(int domain, int type, int protocol);

参数说明:

domain :  地址族    

         IPV4:  AF_INET

         IPV6:  AF_INET6

type :  协议类型   

         SOCK_STREAM :流式协议

         SOCK_DGRAM  :报文协议

protoal:  0 

返回值: 成功返回新的套接字

失败返回-1

绑定地址和端口号

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

参数说明:

sockfd :监听文件描述符

addr  :  打包网络字节序地址和端口号结构体变量的地址

addrlen:  结构体的长度

返回值:成功返回0, 失败返回-1

例:bind(sockfd, (struct sockaddr*)&seraddr, addrlen);

通知内核监听套接字

int listen(int sockfd, int backlog);

参数说明:

sockfd :监听文件描述符

backlog:  设置监听队列的长度

返回值:成功返回0, 失败返回-1

listen(sockfd, 10)

等待接收客户端

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数说明:

sockfd :监听文件描述符

addr  :通用地址结构体变量地址, (保存请求连接客户端的IP + PORT)

addrlen:  保存结构体长度变量的地址

返回值: 成功返回新的套接字, 专门和对应的客户端通讯(全双工)

失败返回-1

ps : accept是一个阻塞函数, 如果没有客户端请求连接, 会一直阻塞等待, 一旦有客户端连接,解除阻塞,接收客户端

cfd = accept(sockfd, (struct sockaddr*)&cliaddr, &addrlen);

端口复用

int opt = 1;

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

client客户端

创建监听套接字

int socket(int domain, int type, int protocol);

参数说明:

domain :  地址族    

              IPV4:  AF_INET

              IPV6:  AF_INET6

type :  协议类型   

              SOCK_STREAM :流式协议

              SOCK_DGRAM  :报文协议

protoal:  0 

返回值: 成功返回新的套接字

失败返回-1

2、请求连接

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

参数说明:

sockfd  : 套接字

addr   :  存放服务器地址和端口号的地址族结构体变量地址

addrlen:  结构体长度

返回值:  成功返回0, 失败返回-1

例:ret = connect(sockfd, (struct sockaddr*)&seraddr, addrlen);

select函数

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

参数说明:

nfds:  最大文件描述符+1

readfds: 监听读集合地址

writefds: 监听写集合地址    NULL

exceptfds: 监听异常集合地址   NULL

timeout : 设置超时时间  

struct timeval {

long    tv_sec;         /* seconds */

long    tv_usec;        /* microseconds */

};

返回值:

>0:  返回准备好的文件描述符个数

=0:   超时时间到了

-1:   错误

例:ret = select(maxfd+1, &rset, NULL, NULL, &tv);

辅助函数:

void FD_CLR(int fd, fd_set *set);  //将fd从set集合中移除

int  FD_ISSET(int fd, fd_set *set); //判断fd是否在set集合中,如果在返回真,否则返回假

void FD_SET(int fd, fd_set *set); // 将fd加入set集合中

void FD_ZERO(fd_set *set);  //  清空set集合中的内容

epoll监听函数

创建集合空间

   int epoll_create(int size);

参数:

size  : 指定文件描述符的个数

返回值:

成功:返回与集合关联的文件描述符

失败:  -1

2、管理集合空间中的文件描述符

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

       参数说明:

epfd:和集合关联的文件描述符

op :  命令参数

      EPOLL_CTL_ADD:  往集合中添加文件描述符

      EPOLL_CTL_MOD: 修改集合中文件描述符的信息

      EPOLL_CTL_DEL:  删除集合中指定的文件描述符

fd:  操作的文件描述符

event:  如果是删除操作,该参数忽略,直接传NULL

         如果是添加操作, 通过该参数告诉内核监听指定文件描述符的指定时间

 typedef union epoll_data {

               void        *ptr;

               int          fd;

               uint32_t     u32;

               uint64_t     u64;

           } epoll_data_t;

           struct epoll_event {

               uint32_t     events;      /* Epoll events */

               epoll_data_t data;        /* User data variable */

           };

         

           events:        EPOLLIN(读事件)

3、监听集合中的文件描述符

 int epoll_wait(int epfd, struct epoll_event *events,

                      int maxevents, int timeout);

参数说明:

epfd:和集合关联的文件描述符

events:存放准备好文件描述符信息数组的起始地址

maxevents:  数组的最大元素个数

timeout  :设置超时时间   (以毫秒为单位的)

          >0  : 指定超时时间

                =0  : 非阻塞函数

                -1  : 永久阻塞

返回值:

>0 : 准备好的文件描述符个数

=0 :超时时间到了

-1 :出错

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值