网络编程1-基本概念、函数接口

一、网络基本概要

1、网络通信概念:

        不同主机的进程间通信

2、IP地址:

  • 概念:类似于就是网络中身份证 ---- 用来唯一的标识一台主机 ,由网络地址和主机号组成
    • 便于记忆,利用点分十进制表示法(类似于192.168.1.1)
    • 主机号为0的IP地址是网络地址,主机号为255的地址是广播地址

3、子网掩码:

  • 概念:用来区分IP地址中的网络地址和主机地址,搭配IP地址使用
    • 子网掩码1:对应IP地址的网络位
    • 子网掩码0:对应IP地址的主机位

4、端口号:

  • 概念:16位的数值0-65535
  • 作用:唯一的标识一个进程,每一个应用的进程都有一个端口号,通讯时用来区分数据包属于哪个进程
  • 分类
    • 任何TCP/IP实现所提供的服务都用1-1023之间的端口号:
      • http:80         FTP:20/2        HTTPS: 443         TFPT: 69          
    • 端口号从1024-49151是被注册的端口号,被IANA指定为特殊服务使用
    • 从49152-65535是动态或私有端口号
      • 所以代码调试时,常使用端口号50000的

5、网络配置:

  • ping IP地址/域名
    • eg: ping www.baidu.com
  • ifconfig 查看当前操作系统中网卡信息
    • ens33:虚拟机中的网卡
    • lo:回环地址(127.0.0.1)
    • inet:IPv4地址
    • netmask:子网掩码
    • broadcast:广播号
    • inet6:IPv6地址
    • ether:MAC地址 

6、国际网络体系结构

  • OSI模型: open system interconnect           理论模型
    •  应用层:要传输的数据信息,如文件传输,电子邮件等
    • 表示层:数据加密,解密操作,压缩,解压缩
    • 会话层:建立数据传输通道
    • 传输层:传输的方式  UDP  TCP   端口
    • 网络层:实现数据路由    路由器  ip
    • 数据链路层:封装成帧,点对点通信(局域网内通信),差错检测   交换机  ARP
    • 物理层:定义物理设备标准,比如网线,光纤等传输介质   比特流  bit  0 1
  • TCP/IP模型:  工业模型   4层
    • 应用层:HTTP、HTTPS、FTP、TFTP、MQTT
    • 传输层:TCP、UDP
    • 网络层:IP
    • 网络接口层:网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准确无误的线
  • TCP模型:5层
    • 应用层:HTTP、HTTPS、FTP、TFTP、MQTT
      • 传输层:TCP、UDP
      • 网络层:IP
      • 数据链路层:封装成帧,点对点通信(局域网内通信),差错检测   交换机
      • 物理层:定义物理设备标准,比如网线,光纤等传输介质   比特流  bit

7、基本协议:

  • 应用层协议:
    • FTP:文件传输协议(实现文件上传/下载)
    • TFTP:简单文件传输协议(实现文件上传/下载)
    • HTTP:超文本传输协议(实现超文本(集视频、图片、文字于一体的文件类型)传输)
    • HTTPS:加密版超文本传输协议
    • MQTT:消息队列遥测传输协议(物联网传输)
  • 传输层协议:
    • UDP:用户数据报协议
    • TCP:传输控制协议

    8、TCP与UDP协议

    • TCP(即传输控制协议)
      • 特点:面向连接、可靠、字节流
      • 注重于:可靠性、稳定性
      • 实际应用:类似打电话
      • 是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)
      • 适用情况:
        • 适合于对传输质量要求较高,以及传输大量数据的通信。
        • 在需要可靠数据传输的场合,通常使用TCP协议
        • MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议
    • UDP(用户数据报协议)
      • 特点:无连接、不可靠、数据报
      • 注重于:实时性、效率高
      • 实际应用:早期监控(似直播,有服务器接收)想要稳定(会借鉴tcp的协议,稳定性)
      • 可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。
      • 适用情况:
        • 发送小尺寸数据(如对DNS服务器进行IP地址查询时)
        •  在接收到数据,给出应答较困难的网络中使用UDP。(如:无
          线网络)
        •  适合于广播/组播式通信中。
        •  MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通
          讯通常采用UDP协议
        •  流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP
          方式进行实时数据传输

    二、函数接口

    1、socket 

    原型: 

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

    头文件:

                    #include <sys/types.h>          /* See NOTES */
                    #include <sys/socket.h>

    功能:

                    创建一个套接字文件(用来通信的接口(文件描述符))

    参数:

    • domain:协议族/地址族(address family)   
      • 常用[AF_INET]、[AF_INET6]
    • typ:数据传输方式
      • 常用[SOCK_STREAM]、[SOCK_DGRAM]
    • protocol:协议
      • 通常为0,表示让系统自动选择最匹配的协议

    返回值:

                    成功:返回socket对应的文件描述符(fd)

                    失败:返回-1

    IPv4地址形式:
            struct sockaddr_in {
               sa_family_t    sin_family; /* address family: AF_INET */
               in_port_t      sin_port;   /* port in network byte order */
               struct in_addr sin_addr;   /* internet address */
           };

           /* Internet address. */
           struct in_addr {
               uint32_t       s_addr;     /* address in network byte order */
           };

    2、send

    类似于write

    函数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                          const struct sockaddr *dest_addr, socklen_t addrlen);

    功能:        向socket中发送信息

    参数:           sockfd:要操作的socket

                       buf :存放数据的空间

                       len :buf的大小

                       flags :指定读取信息的操作标志-MSG_DONTWAI

    返回值:
            成功返回实际发送字节数
            失败返回-1 

    3、sendto

    函数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                          const struct sockaddr *dest_addr, socklen_t addrlen);

    功能:
            向一个IP地址和端口发送数据信息
            端口号:区分一台主机不同的应用程序(0 - 65535)

    参数:
            sockfd:套接字文件描述符
            buf:发送数据空间首地址
            len:发送数据的长度
            flags:发送数据属性(默认为0)
            dest_addr:目的IP地址和端口
            addrlen:目的IP地址和端口的长度

    返回值:
            成功返回实际发送字节数
            失败返回-1 

    4、recv

    类似于read

    函数原型:ssize_t recv(int sockfd, void *buf, size_t len  , int flags);

    功能:        从socket中接收信息

    参数:        sockfd:要操作的socket

                       buf :存放数据的空间

                       len :buf的大小

                       flags :指定读取信息的操作标志-MSG_DONTWAI

    返回值:  成功 读取到的字节数

                    失败-1

    5、recvfrom

    函数原型:    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                            struct sockaddr *src_addr, socklen_t *addrlen);

    功能:        接收网络发送的数据信息

    参数:        sockfd:套接字文件描述符
                       buf:发送数据空间首地址

                       len:最大能够接收的数据个数

                       flags:属性默认为0

                      src_addr:存放发送端IP地址信息的空间首地址

                      addrlen:想要接收的数据长度的空间首地址

    返回值: 成功返回实际接收字节数

                   失败返回-1

    具有阻塞功能(直到接收到数据,才会继续向下执行)

    6、htons主机转网络字节序

    • 主机:小端或者大端   ----host
    • 网络:统一大端          ----network
      • uint32_t htonl(uint32_t hostlong);          主机转网络
      • uint16_t htons(uint16_t hostshort);         主机转网络
      • uint32_t ntohl(uint32_t netlong);           网络转主机
      • uint16_t ntohs(uint16_t netshort);          网络转主机
        • h:host、n:net、l:long、s:short

    7、inet_addr与inet_ntoa

    函数原型:        in_addr_t inet_addr(const char *cp);


    功能:                  将字符串IP地址转换成二进制IP地址形式

                              cp 表示要用的ip地址的字符串 //点分十进制

    函数原型:      char *inet_ntoa(struct in_addr in);


    功能:                将二进制ip转换成字符串

    8、bind

    函数原型:      int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

    功能:              将一个套接字与IP地址和端口号绑定(只能绑定自己的IP地址)

    参数:              sockfd:套接字文件描述符

                             addr:IP地址和端口号结构体首地址

                             addrlen:长度

    返回值:        成功返回0

                          失败返回-1

    9.listen

    原型:int listen(int sockfd, int backlog);

    功能:监听三次握手链接请求

    参数: sockfd:套接字文件描述符
                backlog:最多允许等待尚未处理的三次握手链接个数

    返回值: 成功返回0

                   失败返回-1

    10、accept

    函数原型: int accept (int sockfd,     struct sockaddr *addr, socklen_t *addrlen);

    功能:         从监听的socket中提取连接请求,完成连接(三次握手)

                         返回已连接的一个新socket

    参数:        sockfd:监听的socket的fd

                       addr :用来存放,客户端的地址信息

                       addrlen : 值结果参数

    返回值: 成功返回 已连接的socket的fd  //专门用于后面通信的

                    失败-1

    注意:  addrlen必须初始化 ,初始成 addr对应sockaddr_in 类型的大小

    11、tcp客户端

     socket
     connect

    12、tcp服务器

     socket
     bind 
     listen
     connfd = accept()

    三、练习

    - 总结

    • tcp情况下:
      • 客户端:
        •  socket
        •  connect
      • 服务器
        •  socket
        •  bind 
        •  listen
        •  connfd = accept()

    1、客户端实现收发功能(配合网络调试助手完成)

    #include "../head.h"

    int main(int arg,char const *argv[])   //主函数传参
    {
        char tmp[256] = {"hello world"};

        int fd = socket(AF_INET,SOCK_STREAM,0);
        if (fd < 0)
        {
            perror("fail to socket");
            return -1;
        }
        printf("fd  = %d\n",fd);


        struct sockaddr_in seraddr;
        seraddr.sin_family = AF_INET;
        seraddr.sin_port = htons(50000);
        seraddr.sin_addr.s_addr = inet_addr("192.168.0.161");

        if (connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
        {
            perror("fail to connect");
            return -1;
        }

        while (1)
        {
            fgets(tmp,sizeof(tmp),stdin);
            tmp[strlen(tmp)-1] = '\0';
            if (0 == strcmp(tmp,".quit"))
            {
                break;
            }
            write(fd,tmp,strlen(tmp)+1);

        }

        close(fd);
        
        return 0;
    }

    2、服务器实现实现收发功能(配合网络调试助手完成)

    #include "../head.h"

    int main(int argc,char const*argv[])
    {
        int fd = 0;

        fd = socket(AF_INET,SOCK_STREAM,0);
        if (fd < 0)
        {
            perror("fail to socket");
            return -1;
        }
        printf("fd = %d\n",fd);
        struct sockaddr_in seraddr;
        bzero(&seraddr,sizeof(seraddr)); //初始化
        seraddr.sin_family = AF_INET;
        seraddr.sin_port = htons(50000);
        seraddr.sin_addr.s_addr = inet_addr("192.168.0.162");
        if (bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
        {
            perror("fail to bind");
            return -1;
        }

        if (listen(fd,5) < 0)
        {
            perror("fail to listen");
            return -1;
        }
    #if 0

        int connfd = accept(fd,NULL,NULL);
        if (connfd < 0 )
        {
            perror("fail to accept");
            return -1;
        }

        write(connfd,"hello",6);
        printf("----client connect---\n");
        printf("-----连接成功-----\n");
    #endif

        struct sockaddr_in cliaddr;
        bzero(&cliaddr,0);
        socklen_t len = sizeof(cliaddr);
        int connfd = accept(fd,(struct sockaddr *)&cliaddr,&len);
        if (connfd < 0)
        {
            perror("accept fail");
            return -1;
        }

        printf("----client connect---\n");
        printf("client ip:%s\n",inet_ntoa(cliaddr.sin_addr));
        printf("port :%d\n",ntohs(cliaddr.sin_port));

        return 0;
    }

     

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值