Linux 网络编程 —— 网络基础与相关 API

目录

1. 网络基础

1.1 TCP/IP协议

1.2 网络的体系结构

1.3 TCP/IP协议族体系

1.4 网络预备知识

1.4.1 socket

1.4.2 IP地址

1.4.3 端口号

1.4.4 字节序

1.4.5 字节转换函数

1.4.6 TCP/UDP对比

2. TCP 编程 API

2.1 socket 函数

2.2 bind 函数

2.3 listen 函数

2.4 accept函数

2.5 客户端连接函数 connect

 3. UDP 编程

3.1 send 函数

3.2 recv 函数

4. 并发服务器


1. 网络基础

1.1 TCP/IP协议

  • 用来检测网络传输中差错的传输控制协议 TCP
  • 专门负责对不同网络进行互联的互联网协议 IP

1.2 网络的体系结构

  • 网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起
  • 每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务。
  • 网络体系结构即指网络的层次结构和每层所使用的协议的集合。
  • 两类非常重要的体系结构:OSI和 TCP/IP
  • OSI模型相关的协议已经很少使用,但模型本身非常通用
  • OSI模型是一个理想化的模型,尚未有完整的实现
  • OSI模型共有七层

Linux 网络编程 —— 网络基础与相关 API_第1张图片

1.3 TCP/IP协议族体系

  • TCP/IP协议族体系是Internet事实上的工业标准。
  • 一共有四层
应用层 Relnet,FTP,HTTP,DNS,SMTP等
传输层 TCP和UDP
网络层 IP,ICMP和IGMP,端到端传输
网络接口和物理层 以太网,令牌环网,FDDI,wifi,gps/2G/3G/4G,驱动(屏蔽硬件差异)

1.4 网络预备知识

1.4.1 socket

        是一个编程接口,是一个特殊的文件描述符(对他执行IO的操作函数,比如read,write,close等),并不仅限于TCP/IP协议,面向连接TCP,无连接UDP。

        socket代表网络编程的一种资源

       分类:

  • 1.流式套接字(SOCK_STREAM)。唯一对应 TCP 提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发送顺序接收。内射击流量控制,避免数据流淹没慢的接收方。数据被看作式字节流,无长度限制。
  • 2.数据包套接字(SOCK_DGRAM)。唯一对应UDP提供无连接服务器,数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
  • 3.原始套接字(SOCK_RAW)。对应多个协议,发送穿透了传输层可以对较低层次协议如IP,ICMP直接访问。

1.4.2 IP地址

        IP地址是Internet中主机的标识,Internet中的主机要与别的机器通信必须具有一个IP地址,IP地址为32为(Ipv4)或者128位(Ipv6),每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由

        表示的形式:常用点分形式,如202.38.64.10,最后都会转化成一个32位的无符号整数

1.4.3 端口号

  • 16位数字,1-65535,
  • 为了区分一台主机接收到的数据包应该转交给哪个任务进程处理,使用端口号来区别
  • 预留端口,1-1023(FTP:24, SSH:22, HTTP: 80 ,HTTPS :469)
  • 保留端口:1024-5000(不建议使用)
  • 可以使用的端口: 5000~65535
  • TCP端口号于UDP端口号独立
  • 网络里的通信是由 IP地址+端口号 来决定的

1.4.4 字节序

小端模式:将低序字节存储在起始地址

大端模式:将高序字节存储在起始地址

  • 字节序是指不同的CPU访问内存中的多字节数据时候,存在大小端的问题
  • 如果CPU访问的是字符串,则不存在大小端问题
  • 一般来说X86/ARM : 小端模式
  • power/miop:arm作为路由时,大端模式
  • 网络传输的时候采用大端模式

Linux 网络编程 —— 网络基础与相关 API_第2张图片

1.4.5 字节转换函数

#include 

uint16_t htons(uint16_t host16bitvalue);    //返回网络字节序的值
uint32_t htonl(uint32_t host32bitvalue);    //返回网络字节序的值
uint16_t ntohs(uint16_t net16bitvalue);     //返回主机字节序的值
uint32_t ntohl(uint32_t net32bitvalue);     //返回主机字节序的值

h代表host,n代表net,s代表short(两个字节),l代表long(4个字节),通过上面的4个函数可以实现主机字节序和网络字节序之间的转换。有时可以用INADDR_ANY,INADDR_ANY指定地址让操作系统自己获取

1.4.6 TCP/UDP对比

Linux 网络编程 —— 网络基础与相关 API_第3张图片

2. TCP 编程 API

Linux 网络编程 —— 网络基础与相关 API_第4张图片

2.1 socket 函数

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

参数
    domain
        AF_INET
        AF_INET6
        AF_UNIX,AF_LOCAL
        AF_NETLINK
        AF_PACKET
    type
        SOCK_STREAM: 流式套接字,唯一对应于TCP
        SOCK_DGRAM:数据报套接字,唯一对应着UDP
        SOCK_RAW:原始套接字
    protocol
        一般填0,原始套接字编程时需填充

    返回值
        成功返回文件描述符
        出错返回-1

如果是IPV6编程,要使用struct sockddr_in6结构体(man 7 IPV6),通常使用struct sockaddr_storage来编程。

2.2 bind 函数

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

    参数
        sockfd:通过socket()函数拿到的fd
        addr:采用struct sockaddr的结构体地址,通用结构体

            struct sockaddr{
            sa_family_t sa_family;
            char sa_data[4];}

            struct sockaddr_in{ 基于Internel通信结构体
            as_family_t sin_family;
            in_port_t sin_port;
            struct in_addr sin_addr;
            sin_zero , //填充字节,需清零
            }

            struct in_addr{
            uint32_t s_addr;
            }

    addrlen:地址长度

一般情况下都是对 sockaddr_in 结构体进行初始化赋值,然后强制转换为 sockaddr 类型传入 bind 函数进行绑定。

2.3 listen 函数

int listen(int sockfd,int backlog);

参数:
    sockfd: 通过socket()函数拿到的fd;
    backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。

内核中服务器的套接字fd会维护2个链表
    1.正在三次握手的客户端链表(数量=2*backlog+1)
    2.已经建立好连接的客户端链表(已经完成三次握手分配好了的newfd)

返回值:
    成功返回0
    出错返回-1

listen(fd,5);//表示系统允许11(2*5+1)个客户端同时进行三次握手

2.4 accept函数

阻塞等待客户端连接请求

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

参数
    sockfd:经过前面socket()创建并通过bind(),listen()设置过的fd
    addr:指向存放地址信息的结构体的首地址,获取客户端IP地址和端口号
    addrlen:存放地址信息的结构体的大小

返回值
    成功,返回返回已经建立连接的新的newfd
    出错,返回-1

2.5 客户端连接函数 connect

int connect (int sockfd, struct sockaddr * serv_addr, int addrlen)

参数:
    sockfd:通过socket()函数拿到的fd
    addr:struct sockaddr的结构体变量地址
    addrlen:地址长度

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

 3. UDP 编程

Linux 网络编程 —— 网络基础与相关 API_第5张图片

bind:绑定服务器:TCP地址和端口号
receivefrom:阻塞等待客户端数据
sendto:指定服务器的IP地址和端口号,要发送的数据

3.1 send 函数

ssize_t send(int sockfd,const void *buf,size_t len,int flags);

参数:
    sockfd:socket函数返回的fd
    buffer:发送缓冲区首地址
    length:发送的字节
    flags:发送方式(通常为0),作用和write一样
        MSG_DONTWAIT,非阻塞
        MSG_OOB:用于TCP类型的带外数据(out of band)

返回值:
    成功:实际发送的字节数
    失败:-1,并设置errno

3.2 recv 函数

int recv( SOCKET s, char FAR *buf, int len, int flags);

    flag:一般填0,和read作用一样
        特殊的标志:
        MSG_DONTWAIT
        MSG_OOB:读取带外数据
        MSG_PEEK:流

4. 并发服务器

  • 1.TCP多线程服务器
  • 2.TCP多进程并发服务器

Linux 网络编程 —— 网络基础与相关 API_第6张图片

你可能感兴趣的:(网络,linux,tcp/ip)