⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendrecv.c

📁 Apache 2.0.63 is the current stable version of the 2.0 series, and is recommended over any previous
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr_arch_networkio.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_network_io.h"
#include "apr_lib.h"
#include "apr_arch_file_io.h"
#if APR_HAVE_TIME_H
#include <time.h>
#endif

/* MAX_SEGMENT_SIZE is the maximum amount of data that will be sent to a client
 * in one call of TransmitFile. This number must be small enough to give the 
 * slowest client time to receive the data before the socket timeout triggers.
 * The same problem can exist with apr_socket_send(). In that case, we rely on
 * the application to adjust socket timeouts and max send segment 
 * sizes appropriately.
 * For example, Apache will in most cases call apr_socket_send() with less
 * than 8193 bytes.
 */
#define MAX_SEGMENT_SIZE 65536
#define WSABUF_ON_STACK 50

APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
                                          apr_size_t *len)
{
    apr_ssize_t rv;
    WSABUF wsaData;
    int lasterror;
    DWORD dwBytes = 0;

    wsaData.len = *len;
    wsaData.buf = (char*) buf;

#ifndef _WIN32_WCE
    rv = WSASend(sock->socketdes, &wsaData, 1, &dwBytes, 0, NULL, NULL);
#else
    rv = send(sock->socketdes, wsaData.buf, wsaData.len, 0);
    dwBytes = rv;
#endif
    if (rv == SOCKET_ERROR) {
        lasterror = apr_get_netos_error();
        *len = 0;
        return lasterror;
    }

    *len = dwBytes;

    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, char *buf,
                                          apr_size_t *len) 
{
    apr_ssize_t rv;
    WSABUF wsaData;
    int lasterror;
    DWORD dwBytes = 0;
    DWORD flags = 0;

    wsaData.len = *len;
    wsaData.buf = (char*) buf;

#ifndef _WIN32_WCE
    rv = WSARecv(sock->socketdes, &wsaData, 1, &dwBytes, &flags, NULL, NULL);
#else
    rv = recv(sock->socketdes, wsaData.buf, wsaData.len, 0);
    dwBytes = rv;
#endif
    if (rv == SOCKET_ERROR) {
        lasterror = apr_get_netos_error();
        *len = 0;
        return lasterror;
    }

    *len = dwBytes;
    return dwBytes == 0 ? APR_EOF : APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
                                           const struct iovec *vec,
                                           apr_int32_t nvec, apr_size_t *nbytes)
{
    apr_status_t rc = APR_SUCCESS;
    apr_ssize_t rv;
    int i;
    DWORD dwBytes = 0;
    WSABUF *pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
                                                : malloc(sizeof(WSABUF) * (nvec));

    if (!pWsaBuf)
        return APR_ENOMEM;

    for (i = 0; i < nvec; i++) {
        pWsaBuf[i].buf = vec[i].iov_base;
        pWsaBuf[i].len = vec[i].iov_len;
    }
#ifndef _WIN32_WCE
    rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL);
    if (rv == SOCKET_ERROR) {
        rc = apr_get_netos_error();
    }
#else
    for (i = 0; i < nvec; i++) {
        rv = send(sock->socketdes, pWsaBuf[i].buf, pWsaBuf[i].len, 0);
        if (rv == SOCKET_ERROR) {
            rc = apr_get_netos_error();
            break;
        }
        dwBytes += rv;
    }
#endif
    if (nvec > WSABUF_ON_STACK) 
        free(pWsaBuf);

    *nbytes = dwBytes;
    return rc;
}


APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock,
                                            apr_sockaddr_t *where,
                                            apr_int32_t flags, const char *buf, 
                                            apr_size_t *len)
{
    apr_ssize_t rv;

    rv = sendto(sock->socketdes, buf, (*len), flags, 
                (const struct sockaddr*)&where->sa, 
                where->salen);
    if (rv == SOCKET_ERROR) {
        *len = 0;
        return apr_get_netos_error();
    }

    *len = rv;
    return APR_SUCCESS;
}


APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from, 
                                              apr_socket_t *sock,
                                              apr_int32_t flags, 
                                              char *buf, apr_size_t *len)
{
    apr_ssize_t rv;

    rv = recvfrom(sock->socketdes, buf, (*len), flags, 
                  (struct sockaddr*)&from->sa, &from->salen);
    if (rv == SOCKET_ERROR) {
        (*len) = 0;
        return apr_get_netos_error();
    }
    (*len) = rv;
    if (rv == 0 && sock->type == SOCK_STREAM)
        return APR_EOF;

    return APR_SUCCESS;
}


static apr_status_t collapse_iovec(char **off, apr_size_t *len, 
                                   struct iovec *iovec, int numvec, 
                                   char *buf, apr_size_t buflen)
{
    if (numvec == 1) {
        *off = iovec[0].iov_base;
        *len = iovec[0].iov_len;
    }
    else {
        int i;
        for (i = 0; i < numvec; i++) {
            *len += iovec[i].iov_len;
        }

        if (*len > buflen) {
            *len = 0;
            return APR_INCOMPLETE;
        }

        *off = buf;

        for (i = 0; i < numvec; i++) {
            memcpy(buf, iovec[i].iov_base, iovec[i].iov_len);
            buf += iovec[i].iov_len;
        }
    }
    return APR_SUCCESS;
}


#if APR_HAS_SENDFILE
/*
 * apr_status_t apr_socket_sendfile(apr_socket_t *, apr_file_t *, apr_hdtr_t *, 
 *                                 apr_off_t *, apr_size_t *, apr_int32_t flags)
 *    Send a file from an open file descriptor to a socket, along with 
 *    optional headers and trailers
 * arg 1) The socket to which we're writing
 * arg 2) The open file from which to read
 * arg 3) A structure containing the headers and trailers to send
 * arg 4) Offset into the file where we should begin writing
 * arg 5) Number of bytes to send out of the file
 * arg 6) APR flags that are mapped to OS specific flags
 */
APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock, 
                                              apr_file_t *file,
                                              apr_hdtr_t *hdtr,
                                              apr_off_t *offset,
                                              apr_size_t *len,
                                              apr_int32_t flags) 
{
    apr_status_t status = APR_SUCCESS;
    apr_ssize_t rv;
    apr_off_t curoff = *offset;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -