线程池以及UDP、socket通信

目录

线程池

UDP通信

本地socket通信


线程池

什么是线程池?

是一个抽象的概念, 若干个线程组合到一起, 形成线程池.

为什么需要线程池?

       多线程版服务器一个客户端就需要创建一个线程! 若客户端太多, 显然不太合适.

       什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。

       实现的时候类似于生产者和消费者.

线程池和任务池:

       任务池相当于共享资源, 所以需要使用互斥锁, 当任务池中没有任务的时候需要让线程阻塞, 所以需要使用条件变量.

如何让线程执行不同的任务?

       使用回到函数, 在任务中设置任务执行函数, 这样可以起到不同的任务执行不同的函数.

UDP通信

TCP:传输控制协议, 面向连接的,稳定的,可靠的,安全的数据流传递

稳定和可靠: 丢包重传

数据有序: 序号和确认序号

流量控制: 滑动窗口

UDP:用户数据报协议

面向无连接的,不稳定,不可靠,不安全的数据报传递---更像是收发短信

UDP传输不需要建立连接,传输效率更高,在稳定的局域网内环境相对可靠

UDP通信相关函数介绍:

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 原地址 传出参数
  • addrlen  发送方地址长度
  • 返回值

成功: 返回读到的字节数

失败: 返回 -1 设置errno

      调用该函数相当于TCP通信的recv+accpt函数

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

                      const struct sockaddr *dest_addr, socklen_t addrlen);

函数说明: 发送数据

参数说明:

  • sockfd 套接字
  • dest_addr 目的地址
  • addrlen 目的地址长度
  • 返回值

成功: 返回写入的字节数

失败: 返回-1,设置errno

UDP的服务器编码流程:

  • 创建套接字  type=SOCK_DGRAM
  • 绑定ip和端口
  • while(1)

    {

收发消--recvfrom

发消息--sendto

    }

  • 关闭套接字--close

UDP客户端流程:

  • 创建套接字--socket
  • while(1)

    {

收发消--recvfrom

发消息--sendto

    }

  • 关闭套接字--close

本地socket通信

查询: man 7 unix 可以查到unix本地域socket通信相关信息:

#include <sys/socket.h>

#include <sys/un.h>

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

函数说明: 创建本地域socket

函数参数:   

domain: AF_UNIX or AF_LOCAL

type: SOCK_STREAM或者SOCK_DGRAM

protocol: 0 表示使用默认协议

函数返回值:

成功: 返回文件描述符.

失败: 返回-1, 并设置errno值.

创建socket成功以后, 会在内核创建缓冲区, 下图是客户端和服务端内核缓冲区示意图.

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

函数说明: 绑定套接字

函数参数:

        socket: 由socket函数返回的文件描述符

        addr: 本地地址

        addlen: 本地地址长度

函数返回值:

        成功: 返回文件描述符.

        失败: 返回-1, 并设置errno值.

需要注意的是: bind函数会自动创建socket文件, 若在调用bind函数之前socket文件已经存在, 则调用bind会报错, 可以使用unlink函数在bind之前先删除文件.

struct sockaddr_un {

    sa_family_t sun_family;  /* AF_UNIX or AF_LOCAL*/

    char sun_path[108];  /* pathname */

};

本地套接字服务器的流程:

  • 可以使用TCP的方式, 必须按照tcp的流程
  • 也可以使用UDP的方式, 必须按照udp的流程

tcp的本地套接字服务器流程:

  • 创建套接字  socket(AF_UNIX,SOCK_STREAM,0)
  • 绑定 struct sockaddr_un &强转
  • 侦听 listen
  • 获得新连接 accept
  • 循环通信 read-write
  • 关闭文件描述符 close

tcp本地套接字客户端流程:

  • 调用socket创建套接字
  • 调用bind函数将socket文件描述和socket文件进行绑定.

     不是必须的, 若无显示绑定会进行隐式绑定,但服务器不知道谁连接了.

  • 调用connect函数连接服务端
  • 循环通信read-write
  • 关闭文件描述符 close
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值