中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

socket_read與socket_recv在PHP中的區別是什么

發布時間:2021-01-19 15:48:31 來源:億速云 閱讀:168 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關socket_read與socket_recv在PHP中的區別是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

代碼如下:


string socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] )
int socket_recv ( resource $socket , string &$buf , int $len , int $flags )


可以看到,從聲明可以看到,一個是把收到的數據通過執行結果返回,另一個是把收到的數據通過引用的形式返回。另一個區別就是,socket_read多了一個type,socket_recv多了一個flags(夠混亂的)。我們先來看看socket_recv的源碼吧!

復制代碼 代碼如下:


PHP_FUNCTION(socket_recv)
{
    zval        *php_sock_res, *buf;
    char        *recv_buf;
    php_socket  *php_sock;
    int         retval;
    long        len, flags;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzll", &php_sock_res, &buf, &len, &flags) == FAILURE) {
        return;
    }

    ZEND_FETCH_RESOURCE(php_sock, php_socket *, &php_sock_res, -1, le_socket_name, le_socket);

    /* overflow check */
    if ((len + 1) < 2) {
        RETURN_FALSE;
    }

    recv_buf = emalloc(len + 1);
    memset(recv_buf, 0, len + 1);

    if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) < 1) {
        efree(recv_buf);

        zval_dtor(buf);
        Z_TYPE_P(buf) = IS_NULL;
    } else {
        recv_buf[retval] = '\0';

        /* Rebuild buffer zval */
        zval_dtor(buf);

        Z_STRVAL_P(buf) = recv_buf;
        Z_STRLEN_P(buf) = retval;
        Z_TYPE_P(buf) = IS_STRING;
    }

    if (retval == -1) {
        PHP_SOCKET_ERROR(php_sock, "unable to read from socket", errno);
        RETURN_FALSE;
    }

    RETURN_LONG(retval);
}

啰里啰嗦一大堆,其實有一行最關鍵:

復制代碼 代碼如下:


if ((retval = recv(php_sock->bsd_socket, recv_buf, len, flags)) < 1) {


可以看到,實際上這個函數就是調用了系統的recv而已,只是把輸入參數和得到的結果都處理了一下,比較好理解。那我們再來看下socket_read,socket_read比系統的recv函數多了一個$type參數,這也是我認為這個函數存在的意義,從文檔里可以看到,type有兩個值,分別是PHP_BINARY_READ和PHP_NORMAL_READ,文檔里有寫,PHP_BINARY_READ表示直接用系統的recv方法,PHP_NORMAL_READ表示會一讀,直到遇到\n 或者 \r,我們來看下源碼:

復制代碼 代碼如下:


//省略一大堆
if (type == PHP_NORMAL_READ) {
    retval = php_read(php_sock, tmpbuf, length, 0);
} else {
    retval = recv(php_sock->bsd_socket, tmpbuf, length, 0);
}


可以看到,如果是PHP_NORMAL_READ模式,其實行為和socket_recv是一樣的,都是用的系統的recv函數,但是如果是PHP_NORMAL_READ,則有很大區別,用了自己實現的php_read函數,那這個php_read是干啥的呢?我們繼續看源碼:

復制代碼 代碼如下:


*t = '\0';
while (*t != '\n' && *t != '\r' && n < maxlen) {
    if (m > 0) {
        t++;
        n++;
    } else if (m == 0) {
        no_read++;
        if (nonblock && no_read >= 2) {
            return n;
            /* The first pass, m always is 0, so no_read becomes 1
             * in the first pass. no_read becomes 2 in the second pass,
             * and if this is nonblocking, we should return.. */
        }

        if (no_read > 200) {
            set_errno(ECONNRESET);
            return -1;
        }
    }

    if (n < maxlen) {
        m = recv(sock->bsd_socket, (void *) t, 1, flags);
    }

    if (errno != 0 && errno != ESPIPE && errno != EAGAIN) {
        return -1;
    }

    set_errno(0);
}


關于socket_read與socket_recv在PHP中的區別是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰顺县| 田东县| 长岭县| 麦盖提县| 贵溪市| 武强县| 新河县| 铜川市| 扎囊县| 桦甸市| 白朗县| 清苑县| 奉新县| 海晏县| 霞浦县| 田阳县| 普格县| 静海县| 进贤县| 南昌市| 蕲春县| 湘乡市| 新龙县| 毕节市| 岗巴县| 祁阳县| 虞城县| 屏南县| 乌兰察布市| 招远市| 襄垣县| 绥德县| 信阳市| 安平县| 泸水县| 吉水县| 墨竹工卡县| 东至县| 通辽市| 延津县| 乐都县|