swoole_client源码解析之send数据

前面我们分析了客户端swoole_client的connect过程,从里面代码可以看出,swClient在connect过程中设置了各种其他动作的回调函数,这里我们接着分析余下的流程,同时把回调函数实现也关注下。

//swoole_client的send函数实现
static PHP_METHOD(swoole_client, send)
{
    char *data;
    zend_size_t data_len;
    zend_long flags = 0;

    //解析输入参数信息,这里解析出了data,data长度信息data_len,flag信息,解析也分新的扩展方式和旧的扩展方式
#ifdef FAST_ZPP
    ZEND_PARSE_PARAMETERS_START(1, 2)
        Z_PARAM_STRING(data, data_len)
        Z_PARAM_OPTIONAL
        Z_PARAM_LONG(flags)
    ZEND_PARSE_PARAMETERS_END();
#else
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags) == FAILURE)
    {
        return;
    }
#endif

    if (data_len <= 0) //数据长度小于等于0
    {
        swoole_php_fatal_error(E_WARNING, "data to send is empty.");
        RETURN_FALSE;
    }

    swClient *cli = client_get_ptr(getThis() TSRMLS_CC);//基于当前php对象swoole_client获取到swoole内部的封装对象信息swClient
    if (!cli)//对象信息为空
    {
        RETURN_FALSE;
    }

    //clear errno
    SwooleG.error = 0;
    int ret = cli->send(cli, data, data_len, flags);//调用swClient的send函数发送数据
    if (ret < 0) //发送失败
    {
        swoole_php_sys_error(E_WARNING, "failed to send(%d) %zd bytes.", cli->socket->fd, data_len);
        zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC);//更新swoole_client的errCode属性信息
        RETVAL_FALSE;
    }
    else
    {
        RETURN_LONG(ret);
    }
}

如开篇所说,我们在connect过程中设置了swClient的send回调函数,我们继续分析这个回调函数的实现,客户端在创建时,基于同步和异步区别,在执行send时,流程是不同的,不同点在于,如果是同步的,则多次发送数据直到发送数据完毕,如果是异步的,通过多路复用的方式处理,这里其实是模拟了异步,不是真正的异步,我们重点看看同步的,异步的代码也贴出来,不做实际分析。

cli->connect = swClient_tcp_connect_sync;//同步回调函数设置
cli->send = swClient_tcp_send_async;//异步回调函数设置
//标准的tcp数据发送,多次发送直到数据发送完成,中间需要判断send返回值做处理
static int swClient_tcp_send_sync(swClient *cli, char *data, int length, int flags)
{
    int written = 0;
    int n;

    assert(length > 0);
    assert(data != NULL);

    while (written < length)
    {
        n = swConnection_send(cli->socket, data, length - written, flags);
        if (n < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else if (errno == EAGAIN)
            {
                swSocket_wait(cli->socket->fd, 1000, SW_EVENT_WRITE);
                continue;
            }
            else
            {
                SwooleG.error = errno;
                return SW_ERR;
            }
        }
        written += n;
        data += n;
    }
    return written;
}
static sw_inline int swConnection_send(swConnection *conn, void *__buf, size_t __n, int __flags)
{
    int retval;
#ifdef SW_USE_OPENSSL
    if (conn->ssl)
    {
        retval = swSSL_send(conn, __buf, __n);
    }
    else
    {
        retval = send(conn->fd, __buf, __n, __flags);
    }
#else
    retval = send(conn->fd, __buf, __n, __flags);//调用linux函数send做发送动作
#endif

#ifdef SW_DEBUG
    if (retval > 0)
    {
        conn->total_send_bytes += retval;//统计实际发送的字节数
    }
#endif

    return retval;
}

异步发送过程代码如下,不做解析,这里重点是调用了reactor的接口去发送,而reactor在做处理时,会用多路复用。

static int swClient_tcp_send_async(swClient *cli, char *data, int length, int flags)
{
    int n = length;
    if (cli->reactor->write(cli->reactor, cli->socket->fd, data, length) < 0)
    {
        if (SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW)
        {
            n = -1;
            cli->socket->high_watermark = 1;
        }
        else
        {
            return SW_ERR;
        }
    }
    if (cli->onBufferFull && cli->socket->out_buffer && cli->socket->high_watermark == 0
            && cli->socket->out_buffer->length >= cli->buffer_high_watermark)
    {
        cli->socket->high_watermark = 1;
        cli->onBufferFull(cli);
    }
    return n;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
swoole_loader72_nzts_x64是一个针对PHP语言的扩展库,用于提供高性能的异步网络通信能力。Swoole是基于C语言开发的,可以让PHP程序实现多进程、多线程、协程等高并发处理的特性。 swoole_loader72_nzts_x64是针对PHP 7.2版本的64位操作系统的扩展库。目前,PHP7已经在性能上有了很大的提升,而swoole_loader72_nzts_x64进一步增强了PHP的并发处理能力。64位操作系统的支持能够更好地利用内存资源,提高程序运行效率。 通过使用swoole_loader72_nzts_x64,可以方便地开发一些高性能的网络应用,比如服务器、Web服务、游戏服务器等。swoole_loader72_nzts_x64提供了一系列的API函数,可以轻松实现TCP/UDP服务器,WebSocket服务器,定时器等功能。 相比于传统的PHP开发方式,swoole_loader72_nzts_x64的优势主要体现在以下几个方面: 1. 高并发:采用多进程/多线程/协程模型,可以同时处理成千上万的并发连接,大大提高了执行效率。 2. 高性能:通过底层C/C++编写,性能优越,能够在高负载的情况下依然保持稳定的性能表现。 3. 异步IO:支持异步非阻塞IO操作,减少了等待时间,提高了性能。 4. 内存管理:有效控制内存的使用,避免了内存泄漏和垃圾回收导致的性能损失。 5.易于使用:提供丰富的API函数和文档,开发者可以快速上手并使用。 总之,swoole_loader72_nzts_x64是一个非常有用的PHP扩展库,可以帮助开发者轻松实现高性能的网络应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值