📄 layer.c
字号:
/* -*- 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 "prprf.h"#include "prlog.h"#include "prnetdb.h"#include "prthread.h"#include "plerror.h"#include "plgetopt.h"#include "prwin16.h"#include <stdlib.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 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){ PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods); PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack;} /* PushLayer */static PRFileDesc *PushNewLayers(PRFileDesc *stack){ PRDescIdentity tmp_identity; PRFileDesc *layer; PRStatus rv; /* push a dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 1"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push a data procesing layer */ layer = PR_CreateIOLayerStub(identity, &myMethods); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); /* push another dummy layer */ tmp_identity = PR_GetUniqueIdentity("Dummy 2"); layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods()); rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer); if (verbosity > quiet) PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack); PR_ASSERT(PR_SUCCESS == rv); return stack;} /* PushLayer */#if 0static 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); popped->dtor(popped); return stack;} /* PopLayer */#endifstatic void PR_CALLBACK Client(void *arg){ PRStatus rv; PRUint8 buffer[100]; 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); PR_ASSERT(PR_SUCCESS == rv); while (minor_iterations-- > 0) { bytes_sent = PR_Send( stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(sizeof(buffer) == bytes_sent); if (verbosity > chatty) PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent); bytes_read = PR_Recv( stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT); if (verbosity > chatty) PR_fprintf(logFile, "Client receiving %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; PRUint8 buffer[100]; PRFileDesc *service; PRUintn empty_flags = 0; PRIntn bytes_read, bytes_sent; PRFileDesc *stack = (PRFileDesc*)arg; PRNetAddr client_address; service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT); if (verbosity > quiet) PR_fprintf(logFile, "Server accepting connection\n"); do { bytes_read = PR_Recv( service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT); if (0 != bytes_read) { if (verbosity > chatty) PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read); PR_ASSERT(bytes_read > 0); bytes_sent = PR_Send( service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT); if (verbosity > chatty) PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent); PR_ASSERT(bytes_read == bytes_sent); } } while (0 != bytes_read); if (verbosity > quiet) PR_fprintf(logFile, "Server shutting down and closing 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 PRInt32 PR_CALLBACK MyRecv( PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout){ char *b = (char*)buf; PRFileDesc *lo = fd->lower; PRInt32 rv, readin = 0, request = 0; rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout); if (verbosity > chatty) PR_fprintf( logFile, "MyRecv sending permission for %d bytes\n", request); if (0 < rv) { if (verbosity > chatty) PR_fprintf( logFile, "MyRecv received permission request for %d bytes\n", request); rv = lo->methods->send( lo, &request, sizeof(request), flags, timeout); if (0 < rv) { if (verbosity > chatty) PR_fprintf( logFile, "MyRecv sending permission for %d bytes\n", request); while (readin < request) { rv = lo->methods->recv( lo, b + readin, amount - readin, flags, timeout); if (rv <= 0) break; if (verbosity > chatty) PR_fprintf( logFile, "MyRecv received %d bytes\n", rv); readin += rv; } rv = readin; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -