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

📄 nblayer.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (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.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "prio.h"#include "prmem.h"#include "prprf.h"#include "prlog.h"#include "prerror.h"#include "prnetdb.h"#include "prthread.h"#include "plerror.h"#include "plgetopt.h"#include "prwin16.h"#include <stdlib.h>#include <string.h>/*** Testing layering of I/O****      The layered server** A thread that acts as a server. It creates a TCP listener with a dummy** layer pushed on top. Then listens for incoming connections. Each connection** request for connection will be layered as well, accept one request, echo** it back and close.****      The layered client** Pretty much what you'd expect.*/static PRFileDesc *logFile;static PRDescIdentity identity;static PRNetAddr server_address;static PRIOMethods myMethods;typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;struct PRFilePrivate{    RcvState rcvstate;    XmtState xmtstate;    PRInt32 rcvreq, rcvinprogress;    PRInt32 xmtreq, xmtinprogress;};typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;static PRIntn minor_iterations = 5;static PRIntn major_iterations = 1;static Verbosity verbosity = quiet;static PRUint16 default_port = 12273;static PRFileDesc *PushLayer(PRFileDesc *stack){    PRStatus rv;    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);    layer->secret = PR_NEWZAP(PRFilePrivate);    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);    PR_ASSERT(PR_SUCCESS == rv);    if (verbosity > quiet)        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);    return stack;}  /* PushLayer */static PRFileDesc *PopLayer(PRFileDesc *stack){    PRFileDesc *popped = PR_PopIOLayer(stack, identity);    if (verbosity > quiet)        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);    PR_DELETE(popped->secret);    popped->dtor(popped);    return stack;}  /* PopLayer */static void PR_CALLBACK Client(void *arg){    PRStatus rv;    PRIntn mits;    PRInt32 ready;    PRUint8 buffer[100];    PRPollDesc polldesc;    PRIntn empty_flags = 0;    PRIntn bytes_read, bytes_sent;    PRFileDesc *stack = (PRFileDesc*)arg;    /* Initialize the buffer so that Purify won't complain */    memset(buffer, 0, sizeof(buffer));    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);    if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))    {        if (verbosity > quiet)            PR_fprintf(logFile, "Client connect 'in progress'\n");        do        {            polldesc.fd = stack;            polldesc.out_flags = 0;            polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);            if ((1 != ready)  /* if not 1, then we're dead */            || (0 == (polldesc.in_flags & polldesc.out_flags)))                { PR_ASSERT(!"Whoa!"); break; }            if (verbosity > quiet)                PR_fprintf(                    logFile, "Client connect 'in progress' [0x%x]\n",                    polldesc.out_flags);            rv = PR_GetConnectStatus(&polldesc);            if ((PR_FAILURE == rv)            && (PR_IN_PROGRESS_ERROR != PR_GetError())) break;        } while (PR_FAILURE == rv);    }    PR_ASSERT(PR_SUCCESS == rv);    if (verbosity > chatty)        PR_fprintf(logFile, "Client created connection\n");    for (mits = 0; mits < minor_iterations; ++mits)    {        bytes_sent = 0;        if (verbosity > quiet)            PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));        do        {            if (verbosity > chatty)                PR_fprintf(                    logFile, "Client sending %d bytes\n",                    sizeof(buffer) - bytes_sent);            ready = PR_Send(                stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,                empty_flags, PR_INTERVAL_NO_TIMEOUT);            if (verbosity > chatty)                PR_fprintf(logFile, "Client send status [%d]\n", ready);            if (0 < ready) bytes_sent += ready;            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))            {                polldesc.fd = stack;                polldesc.out_flags = 0;                polldesc.in_flags = PR_POLL_WRITE;                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);                if ((1 != ready)  /* if not 1, then we're dead */                || (0 == (polldesc.in_flags & polldesc.out_flags)))                    { PR_ASSERT(!"Whoa!"); break; }            }            else break;        } while (bytes_sent < sizeof(buffer));        PR_ASSERT(sizeof(buffer) == bytes_sent);        bytes_read = 0;        do        {            if (verbosity > chatty)                PR_fprintf(                    logFile, "Client receiving %d bytes\n",                    bytes_sent - bytes_read);            ready = PR_Recv(                stack, buffer + bytes_read, bytes_sent - bytes_read,                empty_flags, PR_INTERVAL_NO_TIMEOUT);            if (verbosity > chatty)                PR_fprintf(                    logFile, "Client receive status [%d]\n", ready);            if (0 < ready) bytes_read += ready;            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))            {                polldesc.fd = stack;                polldesc.out_flags = 0;                polldesc.in_flags = PR_POLL_READ;                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);                if ((1 != ready)  /* if not 1, then we're dead */                || (0 == (polldesc.in_flags & polldesc.out_flags)))                    { PR_ASSERT(!"Whoa!"); break; }            }            else break;        } while (bytes_read < bytes_sent);        if (verbosity > chatty)            PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);        PR_ASSERT(bytes_read == bytes_sent);    }    if (verbosity > quiet)        PR_fprintf(logFile, "Client shutting down stack\n");        rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);}  /* Client */static void PR_CALLBACK Server(void *arg){    PRStatus rv;    PRInt32 ready;    PRUint8 buffer[100];    PRFileDesc *service;    PRUintn empty_flags = 0;    struct PRPollDesc polldesc;    PRIntn bytes_read, bytes_sent;    PRFileDesc *stack = (PRFileDesc*)arg;    PRNetAddr client_address;    do    {        if (verbosity > chatty)            PR_fprintf(logFile, "Server accepting connection\n");        service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);        if (verbosity > chatty)            PR_fprintf(logFile, "Server accept status [0x%p]\n", service);        if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))        {            polldesc.fd = stack;            polldesc.out_flags = 0;            polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT;            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);            if ((1 != ready)  /* if not 1, then we're dead */            || (0 == (polldesc.in_flags & polldesc.out_flags)))                { PR_ASSERT(!"Whoa!"); break; }        }    } while (NULL == service);    PR_ASSERT(NULL != service);            if (verbosity > quiet)        PR_fprintf(logFile, "Server accepting connection\n");    do    {        bytes_read = 0;        do        {            if (verbosity > chatty)                PR_fprintf(                    logFile, "Server receiving %d bytes\n",                    sizeof(buffer) - bytes_read);            ready = PR_Recv(                service, buffer + bytes_read, sizeof(buffer) - bytes_read,                empty_flags, PR_INTERVAL_NO_TIMEOUT);            if (verbosity > chatty)                PR_fprintf(logFile, "Server receive status [%d]\n", ready);            if (0 < ready) bytes_read += ready;            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))            {                polldesc.fd = service;                polldesc.out_flags = 0;                polldesc.in_flags = PR_POLL_READ;                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);                if ((1 != ready)  /* if not 1, then we're dead */                || (0 == (polldesc.in_flags & polldesc.out_flags)))                    { PR_ASSERT(!"Whoa!"); break; }            }            else break;        } while (bytes_read < sizeof(buffer));        if (0 != bytes_read)        {            if (verbosity > chatty)                PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);            PR_ASSERT(bytes_read > 0);            bytes_sent = 0;            do            {                ready = PR_Send(                    service, buffer + bytes_sent, bytes_read - bytes_sent,                    empty_flags, PR_INTERVAL_NO_TIMEOUT);                if (0 < ready)                {                    bytes_sent += ready;                }                else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))                {                    polldesc.fd = service;                    polldesc.out_flags = 0;                    polldesc.in_flags = PR_POLL_WRITE;                    ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);                    if ((1 != ready)  /* if not 1, then we're dead */                    || (0 == (polldesc.in_flags & polldesc.out_flags)))                        { PR_ASSERT(!"Whoa!"); break; }                }                else break;            } while (bytes_sent < bytes_read);            PR_ASSERT(bytes_read == bytes_sent);            if (verbosity > chatty)                PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent);        }    } while (0 != bytes_read);    if (verbosity > quiet)        PR_fprintf(logFile, "Server shutting down stack\n");    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);}  /* Server */static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd){    PR_DELETE(fd->secret);  /* manage my secret file object */    return (PR_GetDefaultIOMethods())->close(fd);  /* let him do all the work */}  /* MyClose */static PRInt16 PR_CALLBACK MyPoll(    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags){    PRInt16 my_flags, new_flags;    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;    if (0 != (PR_POLL_READ & in_flags))    {        /* client thinks he's reading */        switch (mine->rcvstate)        {            case rcv_send_credit:                my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;                break;            case rcv_data:            case rcv_get_debit:                my_flags = in_flags;            default: break;        }    }    else if (0 != (PR_POLL_WRITE & in_flags))    {        /* client thinks he's writing */        switch (mine->xmtstate)        {            case xmt_recv_credit:                my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;

⌨️ 快捷键说明

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