linux高并发网络编程开发(网络编程基础-socket)10_网络开发两种设计模式,网络模型分层,以太网帧协议,IP,UDP,TCP协议,udp和tcp讲解,soc套接字内存模型,大端和小端存储

该章的pdf版本

01 网络开发两种设计模式

1.网络应用程序设计模式:

  • C/S-client/server
    优点:1.协议选用灵活 2. 可以缓存数据
    缺点: 1. 对用户安全构成威胁 2. 开发工作量大, 调试
    困难
  • B/S-browser/server
    优点: 跨平台
    缺点: 只能使用http

2.协议的概念
○ 规则: 数据传输和数据解释的规则
○ 原始协议 ------>(改进、完善)------> 标准协议
○ 典型协议:TCP/UDP HTTP FTP IP ARP
在这里插入图片描述

02 网络模型分层

  • 7层模型 - OSI(开放式系统互联通信参考模型(英语:Open System Interconnection Reference Model)):
    物 (物理层)-- 双绞线, 光纤
    数 (数据链路) – 数据的传输和错误检测
    网 (网络层)-- 为数据包选择路由
    传 (传输层)-- 提供端对端的接口 tcp/udp
    会 (会话层) – 解除或建立与别的节点的联系
    表 (表示层)-- 数据格式化,代码转换,数据加密
    应 (应用层)-- 文件传输,电子邮件,文件服务,虚拟终端

    网络层:
    在这里插入图片描述

  • 4层模型 - TCP/IP: 网络接口层 网络层 传输层 应用层
    v
    除应用层程序员自己做外,其他层都是操作系统(Windows,Linuc操作系统)做。
    在这里插入图片描述
    注意:以下协议是各层比较常见的协议,并不是只有以下的协议。

03 以太网帧协议

— 借助mac地址完成数据报传递
在这里插入图片描述
□arp数据报 --根据IP获取mac地址
在这里插入图片描述实例:
在这里插入图片描述

04 IP协议

IP段格式:
4位版本: ipv4 ipv6
8位生存时间(TTL): 最多能经过多少跳
32位源IP地址: 数据发送端地址
32位目的IP地址: 数据接收端地址
在这里插入图片描述
在这里插入图片描述

05 UDP协议

DP数据包格式:
16位源端口:
16位目的端口:
在这里插入图片描述
进程
-进程ID
-网络环境中

  • ○IP-定位一台主机
  • ○Port-定位一个进程
  • 127.0.0.1:80

-端口:16位
○2的16次方
○65535

06 TCP协议

TCP数据报格式
16位源端口
16位目的端口32位序号
32位确认序号6个标志位
16位滑动窗口
存储空间
在这里插入图片描述

07 tcp-ip四层模型协议封装

在这里插入图片描述

08 udp和tcp讲解

○tcp: 面向连接的安全的流式传输协议

  • 连接的时候, 进行三次握手

  • 数据发送的时候, 会进行数据确认
    □数据丢失之后, 会进行数据重传
    在这里插入图片描述
    ○udp: 面向无连接的不安全的报式传输

  • 连接的时候不会握手

  • 数据发送出去之后就不管了

在这里插入图片描述
如果数据包丢失会全丢不存在丢失一半的情况

09 什么是套接字socket

○什么是socket

  • 网络通信的函数接口
  • 封装了传输层协议
    □tcp
    □udp

○浏览器-http

  • 封装的是tcp

10 套接字内存模型

在这里插入图片描述
socket编程-网络IO编程

  • 读写操作
  • read/wirte
    ○文件描述符
  • 创建一个套接字, 得到是文件描述符
  • 管道:-匿名

管道:
在这里插入图片描述
内核缓冲区。
内存中一块存储空间。
管道的读写两端分别对应一个文件描述符。

套接字:
○创建成功, 得到一个文件描述符fd
○fd操作的是一块内核缓冲区
在这里插入图片描述
默认也是阻塞的(阻塞不阻塞看的是fd类型)。

11 大端和小端存储

网络字节序
○大端:-网络字节序
数据的高位字节-存储在内存的低地址位
○小端:-主机字节序
数据的高位字节-存储在内存的高地址位
常见主机数据是小端存储

12 大小端转换函数

大小端转换函数
头文件: #include
类型:int -> int

  • 主机字节顺序 --> 网络字节顺序
    uint16_t htons(uint16_t hostshort); 端口
    uint32_t htonl(uint32_t hostlong);IP

  • 网络字节顺序 --> 主机字节顺序
    uint16_t ntohs(uint16_t netshort);端口
    uint32_t ntohl(uint32_t netlong);IP

13 IP地址转换函数

a.指定IP-字符串(点分十进制)
○本地IP转网络字节序 字符串–>int(大端方式存储)
int inet_pton(int af, const char *src, void *dst);
参数:
□af
□src
□dest
○网络字节序转本地IP int-> 字符串
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
参数:
□af
af_inet
□src
网络字节序的整形IP
□dst
□size

14 sockaddr数据结构

○sockaddr
○sockaddrin
○sockaddrun
在这里插入图片描述

struct sockaddr{
/* address family, AF_xxx */
sa_family_t sa_family; 
/* 14 bytes of protocol address */
char sa_data[14];
};
struct sockaddr_in {
__kernel_sa_family_t sin_family;// 地址族协议
__be16 sin_port;// 端口
struct in_addr sin_addr;//IP地址
unsigned char __pad[__SOCK_SIZE__ -sizeof(short int) -
sizeof(unsigned short int) -sizeof(struct in_addr)];
};
struct in_addr {
__be32 s_addr;
};

15 网络套接字函数

○int socket(int domain, int type, int protocol);
在这里插入图片描述
○int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
在这里插入图片描述
○int listen(int sockfd, int backlog);
在这里插入图片描述
○int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
在这里插入图片描述
○int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
在这里插入图片描述

16 C/S模型 -TCP --面向连接的可靠数据包传递

○服务器端:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <ctype.h>

int main(int argc, const char* argv[])
{
    // 创建监听的套接字
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket error");
        exit(1);
    }

    // lfd 和本地的IP port绑定
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;    // 地址族协议 - ipv4
    server.sin_port = htons(8888);
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret = bind(lfd, (struct sockaddr*)&server, sizeof(server));
    if(ret == -1)
    {
        perror("bind error");
        exit(1);
    }

    // 设置监听
    ret = listen(lfd, 20);
    if(ret == -1)
    {
        perror("listen error");
        exit(1);
    }

    // 等待并接收连接请求
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    int cfd = accept(lfd, (struct sockaddr*)&client, &len);
    if(cfd == -1)
    {
        perror("accept error");
        exit(1);
    }

    printf(" accept successful !!!\n");
    char ipbuf[64] = {0};
    printf("client IP: %s, port: %d\n", 
           inet_ntop(AF_INET, &client.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
           ntohs(client.sin_port));
    // 一直通信
    while(1)
    {
        // 先接收数据
        char buf[1024] = {0};
        int len = read(cfd, buf, sizeof(buf));
        if(len == -1)
        {
            perror("read error");
            exit(1);
        }
        else if(len == 0)
        {
            printf(" 客户端已经断开了连接 \n");
            close(cfd);
            break;
        }
        else
        {
            printf("recv buf: %s\n", buf);
            // 转换 - 小写 - 大写
            for(int i=0; i<len; ++i)
            {
                buf[i] = toupper(buf[i]);
            }
            printf("send buf: %s\n", buf);
            write(cfd, buf, len);
        }
    }

    close(lfd);

    return 0;
}

○客户端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
客户端可以不bind,操作系统自己选择,但是服务器不可以。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值