首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 服务器 > Apache >

apr实现udp协议的一个有关问题

2013-01-26 
apr实现udp协议的一个问题我修改这个服务端的范例代码想把tcp协议改成udp协议。我把里面的apr_socket_creat

apr实现udp协议的一个问题
我修改这个服务端的范例代码想把tcp协议改成udp协议。我把里面的apr_socket_create这里用apr_socket_create(&s, sa->family, SOCK_DGRAM, APR_PROTO_UDP, mp);也就是用udp协议传输,结果rv = apr_socket_listen(s, DEF_SOCKET_BACKLOG);这里rv就不是success了。这是怎么回事呢,求助?
或者请给我一个用apr实现udp协议的范例让我看一下

/**
 * apr tutorial sample code
 * http://dev.ariel-networks.com/apr/
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <assert.h>

#include <apr_general.h>
#include <apr_file_io.h>
#include <apr_strings.h>
#include <apr_network_io.h>

/* default listen port number */
#define DEF_LISTEN_PORT8081

/* default socket backlog number. SOMAXCONN is a system default value */
#define DEF_SOCKET_BACKLOGSOMAXCONN

/* default buffer size */
#define BUFSIZE4096

/* useful macro */
#define CRLF_STR"\r\n"

static apr_status_t do_listen(apr_socket_t **sock, apr_pool_t *mp);
static int do_serv_task(apr_socket_t *serv_sock, apr_pool_t *mp);

/**
 * Network server sample code
 * Just response to an HTTP GET request, but this is not a true HTTP server.
 * For example, you can test this program as follows,
 *  $ wget http://localhost:8081/etc/hosts
 * @remark Error checks omitted
 */
int main(int argc, const char *argv[])
{
    apr_status_t rv;
    apr_pool_t *mp;
    apr_socket_t *s;/* listening socket */

    apr_initialize();
    apr_pool_create(&mp, NULL);

    rv = do_listen(&s, mp);
    if (rv != APR_SUCCESS) {
        goto error;
    }

    while (1) {
        apr_socket_t *ns;/* accepted socket */
    
        rv = apr_socket_accept(&ns, s, mp);
        if (rv != APR_SUCCESS) {
            goto error;
        }
        /* it is a good idea to specify socket options for the newly accepted socket explicitly */
        apr_socket_opt_set(ns, APR_SO_NONBLOCK, 0);
        apr_socket_timeout_set(ns, -1);
        
        if (!do_serv_task(ns, mp)) {
            goto error;
        }
        apr_socket_close(ns);
    }

    apr_pool_destroy(mp);


    apr_terminate();
    return 0;

 error:
    {
        char errbuf[256];
        apr_strerror(rv, errbuf, sizeof(errbuf));
        printf("error: %d, %s\n", rv, errbuf);
    }
    apr_terminate();
    return -1;
}

/**
 * Create a listening socket, and listen it.
 */
static apr_status_t do_listen(apr_socket_t **sock, apr_pool_t *mp)
{
    apr_status_t rv;
    apr_socket_t *s;
    apr_sockaddr_t *sa;
    
    rv = apr_sockaddr_info_get(&sa, NULL, APR_INET, DEF_LISTEN_PORT, 0, mp);
    if (rv != APR_SUCCESS) {
        return rv;
    }
    
    rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, mp);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    /* it is a good idea to specify socket options explicitly.
     * in this case, we make a blocking socket as the listening socket */
    apr_socket_opt_set(s, APR_SO_NONBLOCK, 0);
    apr_socket_timeout_set(s, -1);
    apr_socket_opt_set(s, APR_SO_REUSEADDR, 1);/* this is useful for a server(socket listening) process */

    rv = apr_socket_bind(s, sa);
    if (rv != APR_SUCCESS) {
        return rv;
    }
    rv = apr_socket_listen(s, DEF_SOCKET_BACKLOG);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    *sock = s;
    return rv;
}

/**
 * Response a file content as a simple HTTP response protocol.
 * We assume that the request's first line is 'GET file-path HTTP/1.x'
 */
static int do_serv_task(apr_socket_t *sock, apr_pool_t *mp)
{
    int is_firstline = TRUE;
    const char *filepath = NULL;

    /* read all inputs from the client */
    /* XXX This is not a precise parser of HTTP requests.
     * Don't misunderstand that apr_socket_recv() returns a line. It just returns a chunk of bytes */
    while (1) {
char buf[BUFSIZE];
apr_size_t len = sizeof(buf) - 1;/* -1 for a null-terminated */



apr_status_t rv = apr_socket_recv(sock, buf, &len);
if (rv == APR_EOF || len == 0) {
    break;
        }
        buf[len] = '\0';/* apr_socket_recv() doesn't return a null-terminated string */
        
        if (is_firstline) {
            char **tokens;
            apr_tokenize_to_argv(buf, &tokens, mp);
            if (tokens[0] && tokens[1] && strcmp(tokens[0], "GET") == 0) {
                filepath = tokens[1];
            }
            is_firstline = FALSE;
        }
        if (strstr(buf, CRLF_STR CRLF_STR)) {/* expect the end of the request. no guarantee */
            break;
        }
    }

    if (filepath) {
        apr_status_t rv;
        apr_file_t *fp;
        
        if ((rv = apr_file_open(&fp, filepath, APR_READ, APR_OS_DEFAULT, mp)) == APR_SUCCESS) {
            const char *resp_hdr;
            apr_size_t len;
            const char *resp_body;

            apr_finfo_t finfo;
            apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
            
            resp_hdr = apr_psprintf(mp, "HTTP/1.0 200 OK" CRLF_STR "Content-Length: %" APR_OFF_T_FMT CRLF_STR CRLF_STR, finfo.size);
            len = strlen(resp_hdr);
            apr_socket_send(sock, resp_hdr, &len);
            
            resp_body = apr_palloc(mp, finfo.size);
            len = finfo.size;
            apr_file_read(fp, (void*)resp_body, &len);
            apr_socket_send(sock, resp_body, &len);
            
            return TRUE;


        }
    }
    
    /* error case */
    {
        const char *resp_hdr = "HTTP/1.0 404 Not Found" CRLF_STR CRLF_STR;
        apr_size_t len = strlen(resp_hdr);
        apr_socket_send(sock, resp_hdr, &len);
        return TRUE;
    }
}


[解决办法]
无连接协议,不要listen

热点排行