Linux网络编程

本文详细介绍了网络编程的基础概念,包括ISO七层模型与TCP/IP四层模型的区别,常见网络协议如TCP、UDP的工作原理,IP地址及子网掩码的使用方法,端口号与字节序的概念,以及基于TCP的服务器与客户端通信流程。

一、网络常识

1.ISO
    OSI七层协议模型
    
    应用层:为应用程序提供服务并规定应用程序中通信相关细节
            包括文件传输(FTP)、电子邮件、远程登录等协议
    表示层:主要负责数据格式的转换
    会话层:主要负责建立连接和断开连接
    -----------------
    传输层:主要起着可靠传输的作用
    网络层:将数据传输到目标地址,主要负责寻址和路由选择
    -----------------
    数据链路层:负责物理层面上的互连的节点之间的通信传输
    物理层:负责0、1比特流与电压的高低、光的闪灭之间的互换


TCP/IP四层协议
    应用层    FTP SMTP HTTP telnet...
    传输层    TCP UDP
    网络层    IP ...
    驱动层    ARP...
    
简单说,协议就是计算机与计算机之间通过网络实现通信时,事先达成的一种 “约定”


2.常用协议
TCP    传输控制协议    是一种面向连接的协议 类似打电话   三次握手  
                    
            
UDP    用户数据报协议    是一种无连接的协议    类似发短信
IP 互联网协议        是上述两种协议的底层协议

3.IP地址
    IP地址  是互联网中的唯一地址标识
        IP
        IPv4    本质就是一个由32位二进制组成的整数
        IPv6                由128位二进制组成的整数
        
        192.168.0.111    点分十进制
        DNS
        www.baidu.com
        
        2^32 个地址,怎么管理?
        将IP地址分成两部分:网络号 + 主机号
        网络号:属于哪一个网络
        主机号:网络中主机的编号
        
        根据网络号和主机号 位数的不同分为4类
        A: 0 + 7位网络号 + 24位主机号
            0.0.0.0 ~127.255.255.255
        B: 10 + 14位网络号 + 16位主机号
            128.0.0.0 ~191.255.255.255
        C:110 + 21位网络号 + 8位主机号
            192.0.0.0 ~ 223.255.255.255
        D:1110 + 28位多播地址
            224.0.0.0 ~239.255.255.255
        E:备用
        
4.子网掩码
    子网掩码主要用于划分IP地址中的网络号和主机号
    也用于判断两个IP是不是在同一个局域网中
    C类地址的默认子网掩码是255.255.255.0
    具体的划分方法:
    IP & 子网掩码 = 网络号
    172.30 .100.64   IP
    255.255.255.0  &
-----------------------
    172.30 .100.0    网络号
    
    例:
    166.111.160.1
    255.255.254.0 &
    
    
    166.111.161.45
    
    子网掩码:255.255.254.0

  
    
5.端口号与字节序
    端口号
    IP地址  定位到具体某一台主机/设备
    端口号    定位到主机/设备上的某一个进程
    
    网络编程中需要提供两个信息:
        IP地址 端口号
    端口号本质上是无符号short类型,范围0~65535
    其中0~1024之间的端口号被系统占用
    建议从1025开始使用。
    
    字节序
    小端系统:主要指将低位字节数据保存在低位内存地址的系统
    大端系统:主要指将低位字节数据保存在高位内存地址的系统
    
    网络发送数据用的是大端模式。


二.网络编程又叫socket编程

1.套接字是一个网络编程的接口,是网络数据传输用的软件设备,用于网络交互。
    网络编程就是编写程序使两台连网的计算机相互交换数据,这就是网络编程的全部内
    容
    
Unix/Linux系统作为服务器存在至今,因此,Linux的网络功能是非常全面和强大的。
网络编程其实有很成熟的通信模型,并且windows也是如此。

2.基于TCP的一对一通信模型
服务器:
    1.创建socket,使用socket函数
    2.准备通信地址,使用结构体类型
    3.绑定socket和通信地址,使用bind函数
    4.监听,设置队列的最大数目 listen
    5.接受连接,accept
    6.进行通信 ,使用read、write
    7.关闭socket,使用close函数
客户端:
    1.创建socket,使用socket函数
    2.准备通信地址,使用的是服务器的地址
    3.连接服务器,使用connect函数
    4.进行通信,使用read、write
    5.关闭socket,使用close函数
    
3.相关API
    #include <sys/types.h>          
    #include <sys/socket.h>

   1. int socket(int domain, int type, int protocol);
    功能:用于创建可以实现通信的交流节点。也就是socket通信的载体
    第一个参数:域/协议族,决定本地通信还是网络通信
                AF_UNIX, AF_LOCAL   本地通信
                AF_INET             用于实现基于IPv4 的网络通信
                AF_INET6            用于实现基于IPv6 的网络通信
                ...
                
    第二个参数:通信的类型,决定具体的通信方式
                SOCK_STREAM     提供有序的、可靠的、双向的、面向连接的字
                                节流通信方式,即基于TCP协议的通信方式

                SOCK_DGRAM      提供不可靠的,无连接的数据报通信方式,
                                即基于UDP协议的通信式。
                ...
    第三个参数:指定具体的协议,默认给0即可。
    返回值:成功返回一个新的socket文件描述符,失败返回 -1,errno被设置
    
    
    2.通信地址:
        a.通用地址结构
            struct sockaddr
            {
                sa_family_t sa_family;   //sa_family_t即无符号的短整型
                char sa_data[14];
            };
        该结构体类型主要用于函数的形参类型,基本不会定义变量使用。
        
        b.IPv4的地址结构
            struct sockaddr_in
            {
                sa_family_t sin_family;//协议族 AF_INET
                in_port_t sin_port;//端口号  16位
                strcut in_addr sin_addr;//IP地址
            };
            strcut in_addr
            {
                in_addr_t s_addr;//整数类型的IP地址 32位
            };
            该结构体类型主要用于实现不同主机之间的网络通信模型中
    
        例:
            struct sockaddr_in sAddr;//定义一个IPv4地址结构
            memset(&sAddr,0,sizeof(sAddr));
            sAddr.sa_family = AF_INET;
            sAddr.sin_port = htons(10086);//端口号 ->转换成网络字节序
            sin_port是两个字节,必须使用网络字节序来保存
            内核提供了几个用来在主机字节序和网络字节序进行转换的函数
             #include <arpa/inet.h>

               uint32_t htonl(uint32_t hostlong);
               uint16_t htons(uint16_t hostshort);
               uint32_t ntohl(uint32_t netlong);
               uint16_t ntohs(uint16_t netshort);
               
               //字符串形式的点分十进制需要转成32位整数
              sAddr.sin_addr.s_addr = inet_addr("192.168.0.110");
              内核也提供了几个函数用于点分式(IP字符串)与网络IP地址之间进行转换
              in_addr_t inet_addr(const char *cp);//char* --> int
              
              char *inet_ntoa(struct in_addr in);//int --> char*
              
    3.bind函数
    int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    功能:主要用于绑定socket和具体的通信地址
    第一个参数:socket函数的返回值,即socket描述符
    第二个参数:结构体指针,即要绑定的地址(协议族,IP地址,端口号)
    第三个参数:地址结构体的大小,sizeof计算即可
    
    返回值:成功返回0
            失败-1,errno被设置
            
    4.listen函数
        int listen(int sockfd, int backlog);
        功能:主要用于监听指定的socket上的连接请求
        第一个参数:socket描述符
        第二个参数:表示同一时刻,允许的最大连接请求数。
        返回值:成功返回0
            失败-1,errno被设置
        
    5.accept函数  //此为阻塞函数
        int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        功能:用于从监听的套接字上接受一个新的连接请求,如果接受了,把 “连接套接字” 返回
        第一个参数:socket函数的返回值,即socket描述符
        第二个参数:结构体指针,用于保存新连接的客户端的通信地址
        第三个参数:地址结构体的大小,sizeof计算即可,注:函数调用者必须初始化
        返回值:成功返回一个连接套接字描述符
                失败返回-1,errno被设置
                
    6.read、write
    7.close


    -----客户端----------
    1.socket函数
    2.准备服务器的地址
    3.连接服务器
        connect函数
        int connect(int sockfd, const struct sockaddr *addr,
                                        socklen_t addrlen);
        功能:用于连接服务器,参数和返回值请参数bind
    4.read、write
    5.close   

    ---------------------
    用TCP传输文件
    服务器(接收文件):
        1.socket
        2.bind
        3.listen
        4.accept
        5.//接收文件
            a.接收文件名称
            b.接收文件大小
            c.接收文件内容
        6.close
        
    客户端(发送文件):
        1.socket
        2.connect
        3.发送文件
            a.发送文件名称
            b.文件大小
            c.文件内容

        4.close



三、socket套接字选项

    套接字选项
    每个套接字在不同的协议层次上有不同的行为属性,我们把这个行为属性称为套接字选项 socket options
    
    这些套接字选项,可以改变或获取
    getsockopt:获取 套接字选项
    setsockopt:设置套接字选项
    
    int getsockopt(int sockfd, int level, int optname,
                      void *optval, socklen_t *optlen);
    功能:用于获取套接字选项
    第一个参数:sockfd,就是要查看的套接字描述符
    第二个参数:要查看的选项的协议层
    第三个参数:保存查看结果的缓冲区地址
    第四个参数:缓冲区大小
    返回值:
        成功返回0
        失败返回-1 ,errno被设置
                      
    int setsockopt(int sockfd, int level, int optname,
                      const void *optval, socklen_t optlen);
    功能:用于设置套接字选项
    参数:参考上面

    //允许地址重用
    int i = 1;    
    res = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(void*)&i,sizeof(int));




  
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cool2Feel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值