Linux环境编程(八)--------------套接字使用(socket),多路复用,TCP和UDP协议的网络通信

一、套接字

基本特点:socket是一种接口技术,被抽象成一个文件操作,可以让进程之间通信,也可以让不同计算机的进程通信(网络)。

  1.  int socket(int domain, int type, int protocol);
    功能:创建套接字
    domain:
        AF_UNIX/AF_LOCAL 本地通信,进程间通信
        AF_INET 基于IPv4地址通信
        AF_INET6 基于IPv6地址通信
    type:
        SOCK_STREAM 数据流协议 
        SOCK_DGRAM 数据报协议
    **protocol:特殊通信协议,一般不用,写0即可**。
    返回值:成功返回套接字描述符,失败返回-12.int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    功能:绑定socket和地址(文件路径或网络地址)
    sockfd:socket描述符
    addr:地址结构体
        // 基本地址类型
        struct sockaddr {
            sa_family_t sa_family;
            char        sa_data[14];
        }
        // 本地地址类型 #include <sys/un.h>
        struct sockaddr_un{
            sa_family_t sun_family; // 地址簇
            char sun_path[108]; // socket文件路径
        };
        // 网络地址类型 #include <netinet/in.h>
        struct sockaddr_in{
            sa_family_t sin_family; // 地址簇
            in_port_t sin_port;     // 端口号
            struct in_addr sin_addr;// IP地址
        };
        struct in_addr{
            in_addr_t s_addr;
        }
    addrlen:地址结构体的字节数
    返回值:成功返回0,失败返回-13.int listen(int sockfd, int backlog);
    功能:监听socket,数据流通信时使用
    sockfd:socket描述符
    backlog:排队数量
    返回值:成功返回0,失败返回-14.int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    功能:连接socket
    sockfd:socket描述符
    addr:目标地址
    addrlen:地址的字节数
    返回值:成功返回0,失败返回-15.int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    功能:等待连接
    sockfd:socket描述符
    addr:获取连接者的地址
    addrlen:既输入双输出
        既告诉accept函数当前系统地址结构体的字节数,同时也获取发者地址结构体的字节数
    返回值:返回一个建议连接后的socket描述符

    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    功能:从socket读取数据,数据流通信时使用
    sockfd:建立连接后的socket描述符
    buf:存储数据的缓冲区地址
    len:缓冲区的字节数
    flags: 一般写0即可
        MSG_OOB 优先接收外带数据
        MSG_DONTWAIT 不阻塞
    返回值:接收到的字节数,-1出现错误,0连接断开。

   6.ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    功能:向socket发送数据,数据流通信时使用
    sockfd:建立连接后的socket描述符
    buf:待发送的数据首地址
    len:要发送的字节数
    flags:一般写0即可
        MSG_OOB 优先紧急数据
        MSG_DONTWAIT 不阻塞
    返回值:成功发送的字节数,出错返回-17.int close(int fd);
    功能:关闭socket

TCP网络通信编程模型:
计算机S 计算机C
创建套接字 创建套接字
准备通信地址(自己的) 准备通信地址(计算机S,与C在同一局域网或S是公用IP)
绑定套接字和地址 连接计算S
监听 …
等待连接 …
接收/发送数据 发送/接收数据
关闭套接字 关闭套接字

多路复用:(我并不太理解)

由于为了实现服务器的并发(同时服务多个客户端),需要为每个客户端创建一个进程来为它服务,但创建进程、销毁进程非常浪费时间与资源,这个问题有两种解决方案:
1、多路复用:一个进程监控所有的客户端fd+服务端fd。
2、多线程:为每个客户端创建一个线程进行服务。

由于有些读写函数需要以阻塞状态调用,同时可能有多个文件描述需要同时读写,多路复用就是同时监控多个文件的描述符。

    int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
    功能:监控若干个文件描述符
    nfds:最大的文件描述符加1
    readfds:需要监控读操作的文件描述符集合,既输入又是输出。
    writefds:需要监控写操作的文件描述符集合,既输入又是输出。
    exceptfds:需要监控异常的文件描述符时间,既输入又是输出。
    timeout:倒计时时间
    struct timeval {
        long    tv_sec;         /* seconds */
        long    tv_usec;        /* microseconds */
    };

    void FD_CLR(int fd, fd_set *set);
    功能:从集合中删除fd

    int  FD_ISSET(int fd, fd_set *set);
    功能:测试集合是否有fd存在

    void FD_SET(int fd, fd_set *set);
    功能:向集合中添加文件描述符

    void FD_ZERO(fd_set *set);
    功能:清空文件描述符

    int epoll_create(int size);
    功能:创建epoll对象
    size:epoll对象的大小,因为内核会自动调整epoll对象的大小,因此该参数目前已经作废。
    返回值:epoll对象的描述符
    
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    功能:操作epoll对象,可以添加、删除文件描述符
    epfd:epoll对象描述符
    op:
        EPOLL_CTL_ADD 添加文件描述符
        EPOLL_CTL_MOD 修改文件描述符的监控事件
        EPOLL_CTL_DEL 删除文件描述符
    fd:
        要操作的文件描述符
    event:
        struct epoll_event {
            uint32_t     events;      /* Epoll events */
                EPOLLIN 读事件
                EPOLLOUT 写事件
            epoll_data_t data;        /* User data variable */
        };

    int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
    功能:监控epoll对象中的文件描述符
    epfd:epoll对象
    events:保存发生事件的文件描述符集合
    maxevents:最多保存多少个文件描述符
    timeout:等待时间,1000/1秒,-1则一直等待。
    返回值:事件发生手文件描述符个数

    常考面试题:select与epoll的区别。

本地字节序与网络字节序转换:
    uint32_t htonl(uint32_t hostlong);
    功能:把4字节的本地字节序数据转换成网络字节序

    uint16_t htons(uint16_t hostshort);
    功能:把2字节的本地字节序数据转换成网络字节序

    uint32_t ntohl(uint32_t netlong);
    功能:把4字节网络字节序数据转换成本地字节序

    uint16_t ntohs(uint16_t netshort);
    功能:把2字节网络字节序数据转换成本地字节序

IPv4地址转换:
    int inet_aton(const char *cp, struct in_addr *inp);
    功能:把点十进制的IP地址转换成 struct sockaddr_in中的sin_addr成员类型。

    in_addr_t inet_addr(const char *cp);
    功能:把点十进制的IP地址转换成 struct sockaddr_in中的sin_addr.s_addr,通过返回值返回。
    
    in_addr_t inet_network(const char *cp);
    功能:把点十进制的IP地址转换成,转换成本地字节序的二进制。

    char *inet_ntoa(struct in_addr in);
    功能:struct sockaddr_in中的sin_addr成员转换成点分十进制的ip地址。

    struct in_addr inet_makeaddr(int net, int host);
    功能:把网络地址与主机地址合并成IP地址

    in_addr_t inet_lnaof(struct in_addr in);
    功能:计算IP地址的主机地址
        ip & ~掩码

    in_addr_t inet_netof(struct in_addr in);
    功能:计算IP地址的网络地址
        ip & 掩码

二、UDP网络通信:

UDP是无连接的通信协议,准备好地址之后可以直接发送或接收数据。

   1.ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
    功能:发送数据
    sockfd:发送者的socket描述符
    buf:待发送的数据
    len:数据的长度
    flags:一般写0即可。
    dest_addr:目标地址
    addrlen:地址的长度
    返回值:成功发送的数据的字节数

   2.ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
    功能:接收数据
    sockfd:接收者的socket描述符
    buf:存储数据的缓冲区
    len:缓冲区的长度
    flags:一般写0即可
    src_addr:存储发送者的地址
    addrlen:既是输入(当前系统地址的字节数)也是输出(获取发送者地址的字节数),存储发送者地址的长度。
    返回值:成功接收到的数据的字节数。

UDP网络通信编程模型:
计算机S 计算机C
创建socket对象 创建socket对象
准备通信地址 准备通信地址(S的地址)
绑定socket对象和地址
接收/返回数据 发送/接收数据
关闭socket对象 关闭socket对象

三、UDP广播通信:

广播就是发送者发出一条数据,路由器把这条数据向局域网中的所有计算转发一次。
如何广播:就是向一个特殊地址发送数据,同时还要设置sock对象的属性。
广播地址就是除了网络地址其它位全为1。
192.168.0.113
255.255.255.0
192.168.0 网络地址
113 主机地址
192.168.0.255 广播地址

   1.int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
    功能:设置socket对象的属性
    sockfd:socket对象的描述符
    level:要设置的协议层
        SOL_SOCKET
            SO_BROADCAST 广播
        IPPROTO_IP
            IP_MULTICAST_TTL 多播
        IPPROTO_TCP
    optname:要设置的选项名
    optval:存储要修改的值的缓冲区
    optlen:缓冲区的长度

   2.int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);
    
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值