阿鑫来了  

socket套接字编程: 网络通信程序的编写 (接口+流程)

    udp协议通信程序的编写 / tcp协议通信程序的编写 

           udp协议: 用户数据报协议 

                 特性: 无连接, 不可靠, 面向数据报

                 应用场景: 应用于实时性要求大于安全性要求的场景 -- 视频传输

           tcp协议: 传输控制协议

                 特性: 面向连接, 可靠传输, 面向字节流

                 应用场景: 应用于安全性要求大于实时性要求的场景 -- 文件传输

在网络通信程序中, 通信两端被分为: 客户端, 服务器端

     客户端:  通常是提供给客服的通信端,  通常是编写通信程序中主动发出请求的一端

     服务端:  通常指被动接受请求,  提供服务的通信端

客户端是主动发送请求的一端,  也就是意味着客户端必须提前能够知道服务端的地址信息(ip+port)

服务端的地址通信通常是固定的,  并且是提前提供给客户端的

 

udp通信程序的编写:  套接字接口

    通信流程

          服务端:  1. 创建套接字 -- 在内核中创建一个socket结构体

                        2. 为套接字绑定地址信息 -- 在创建套接字创建的socket结构体中加入ip+port信息

                                 1. 告诉操作系统主机收到的哪些数据应该交给当前的这个socket

                                 2. 确定发送数据的源端地址信息

                         3. 接收数据 -- 当前进程从指定的socket接收缓冲区中取出数据

                         4. 发送数据 -- 将发送的数据放到socket发送缓冲区中,内核选择合适时候封装发送

                         5. 关闭套接字

 

          客户端:  1. 创建套接字

                        2. 为套接字绑定地址

                                 (大多数情况会忽略第二步,在发送数据时,若socket没有绑定地址,则系统会选择合适的地址绑定)

                        3. 发送数据

                        4. 接收数据

                        5. 关闭套接字

 

接口认识:

        1.  创建套接字     (可以使用 man socket 查看)

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

                     domain :  地址域类型;  一般使用 -- AF_INET-IPv4通信,  使用IPv4的地址结构

                     type :  套接字类型;  SOCK_STREAM / SOCK_DGRAM

                                 udp通信必须使用SOCK_DGRAM;  tcp通信必须使用SOCK_STREAM

                     protocol :  本次通信协议;  IPPROTO_TCP-6 / IPPROTO_UDP-17;

              返回值 :  返回一个文件描述符 -- 操作句柄       失败返回-1

        2.  为套接字绑定地址信息   (可以使用 man 2 bind 查看)

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

                      sockfd :  创建套接字返回的操作句柄

                      addr :  当前绑定的地址信息

                      socklen_t :  地址信息长度

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

       3.  接受数据

               ssize_t recvfrom(int sockfd, void *buf, int len, int flag, struct sockaddr *srcaddr, socklen_t *addrlen)

                        sockfd :  操作句柄

                        buf :  空间地址,  用于存放接收的数据

                        len :  要接收的数据长度

                        flag :  选项标志 - 默认0 - 表示阻塞接收

                        srcaddr :  本条数据的源端地址信息

                        addrlen :  输入输出参数 -- 指定要接收多长的地址结构,  并且返回实际接收的地址长度

                 返回值 :  返回实际接收到的数据长度;  失败返回-1

                                ssize_t -- 有符号int                size_t -- 无符号int

       4. 发送数据

              ssize_t sendto(int sockfd, void *data, int len, int flag, struct scokaddr *peeraddr, socklent_t addrlen)  

                        sockfd :  操作句柄

                        data :  要发送的数据的空间首地址

                        len :  要发送的数据长度

                        flag :  选项标志 - 默认0 - 表示阻塞发送

                        peeraddr :  对端地址信息

                        addrlen :  地址结构长度

               返回值 :  成功返回实际发送的数据长度,  失败返回-1

        5. 关闭套接字

               int close(int fd);

 

字节序转换接口

      uint32_t htonl(uint32_t hostlong);     32位数据主机到网络字节序转换

      uint16_t htons(uint16_t hostshort);   16位数据主机到网络字节序转换

      uint32_t ntohl(uint32_t netlong);        32位数据网络到主机字节序转换

      uint16_t ntohs(uint16_t netshort);      16位数据网络到主机字节序转换

           port端口转换使用s,   ip转换使用l,  不能混用

将字符串点分十进制IP地址转换为整形网络字节序IP地址

      "192.168.2.2" -> 0xc0a80202

             in_addr_t inet_addr(const char *cp);                        (只能实现IPV4转换)

             int inet_pton(int af, const char *src, void *dst);        (IPV4和IPV6都可以转换)

 

将网络字节序IP地址转换为字符串点分十进制IP地址

       0xc0a80202 -> "192.168.2.2"

             char *inet_ntoa(struct in_addr in);                                                             (只能实现IPV4转换)

             const char *inet_ntop(int af, void *src, char *dst, socklen_t size);          (IPV4和IPV6都可以转换)

 

posted on 2021-05-30 17:00  阿鑫来了  阅读(62)  评论(0)    收藏  举报