📄 udpsrv.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. *//********************************************************************* udpsrc.c -- Test basic function of UDP server**** udpsrv operates on the same machine with program udpclt.** udpsrv is the server side of a udp sockets application.** udpclt is the client side of a udp sockets application.**** The test is designed to assist developers in porting/debugging** the UDP socket functions of NSPR.**** This test is not a stress test.**** main() starts two threads: UDP_Server() and UDP_Client();** main() uses PR_JoinThread() to wait for the threads to complete.**** UDP_Server() does repeated recvfrom()s from a socket.** He detects an EOF condition set by UDP_Client(). For each** packet received by UDP_Server(), he checks its content for** expected content, then sends the packet back to UDP_Client().** ** UDP_Client() sends packets to UDP_Server() using sendto()** he recieves packets back from the server via recvfrom().** After he sends enough packets containing UDP_AMOUNT_TO_WRITE** bytes of data, he sends an EOF message.** ** The test issues a pass/fail message at end.** ** Notes:** The variable "_debug_on" can be set to 1 to cause diagnostic** messages related to client/server synchronization. Useful when** the test hangs.** ** Error messages are written to stdout.** *********************************************************************//* --- include files --- */#include "nspr.h"#include "prpriv.h"#include "plgetopt.h"#include "prttools.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#ifdef XP_PC#define mode_t int#endif#define UDP_BUF_SIZE 4096#define UDP_DGRAM_SIZE 128#define UDP_AMOUNT_TO_WRITE (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1)#define NUM_UDP_CLIENTS 1#define NUM_UDP_DATAGRAMS_PER_CLIENT 5#define UDP_SERVER_PORT 9050#define UDP_CLIENT_PORT 9053#define MY_INADDR PR_INADDR_ANY#define PEER_INADDR PR_INADDR_LOOPBACK#define UDP_TIMEOUT 400000/* #define UDP_TIMEOUT PR_INTERVAL_NO_TIMEOUT *//* --- static data --- */static PRIntn _debug_on = 0;static PRBool passed = PR_TRUE;static PRUint32 cltBytesRead = 0;static PRUint32 srvBytesRead = 0;static PRFileDesc *output = NULL;/* --- static function declarations --- */#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg)/********************************************************************* ListNetAddr() -- Display the Net Address on stdout**** Description: displays the component parts of a PRNetAddr struct**** Arguments: address of PRNetAddr structure to display**** Returns: void**** Notes:***********************************************************************/void ListNetAddr( char *msg, PRNetAddr *na ){ char mbuf[256]; sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n", msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) );#if 0 DPRINTF( mbuf ); #endif} /* --- end ListNetAddr() --- *//********************************************************************** UDP_Server() -- Test a UDP server application**** Description: The Server side of a UDP Client/Server application.**** Arguments: none**** Returns: void**** Notes:*************************************************************************/static void PR_CALLBACK UDP_Server( void *arg ){ static char svrBuf[UDP_BUF_SIZE]; PRFileDesc *svrSock; PRInt32 rv; PRNetAddr netaddr; PRBool bound = PR_FALSE; PRBool endOfInput = PR_FALSE; PRInt32 numBytes = UDP_DGRAM_SIZE; DPRINTF("udpsrv: UDP_Server(): starting\n" ); /* --- Create the socket --- */ DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" ); svrSock = PR_NewUDPSocket(); if ( svrSock == NULL ) { passed = PR_FALSE; if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" ); return; } /* --- Initialize the sockaddr_in structure --- */ memset( &netaddr, 0, sizeof( netaddr )); netaddr.inet.family = PR_AF_INET; netaddr.inet.port = PR_htons( UDP_SERVER_PORT ); netaddr.inet.ip = PR_htonl( MY_INADDR ); /* --- Bind the socket --- */ while ( !bound ) { DPRINTF("udpsrv: UDP_Server(): Binding socket\n" ); rv = PR_Bind( svrSock, &netaddr ); if ( rv < 0 ) { if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR ) { if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n"); PR_Sleep( PR_MillisecondsToInterval( 2000 )); continue; } else { passed = PR_FALSE; if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \ PR_Bind(): failed: %ld with error: %ld\n", rv, PR_GetError() ); PR_Close( svrSock ); return; } } else bound = PR_TRUE; } ListNetAddr( "UDP_Server: after bind", &netaddr ); /* --- Recv the socket --- */ while( !endOfInput ) { DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" ); rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT ); if ( rv == -1 ) { passed = PR_FALSE; if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n", PR_GetError() ); PR_Close( svrSock ); return; } ListNetAddr( "UDP_Server after RecvFrom", &netaddr ); srvBytesRead += rv; if ( svrBuf[0] == 'E' ) { DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" ); endOfInput = PR_TRUE; } /* --- Send the socket --- */ DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" ); rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT ); if ( rv == -1 ) { passed = PR_FALSE; if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n", PR_GetError() ); PR_Close( svrSock ); return; } ListNetAddr( "UDP_Server after SendTo", &netaddr ); } /* --- Close the socket --- */ DPRINTF("udpsrv: UDP_Server(): Closing socket\n" ); rv = PR_Close( svrSock ); if ( rv != PR_SUCCESS ) { passed = PR_FALSE; if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" ); return; } DPRINTF("udpsrv: UDP_Server(): Normal end\n" );} /* --- end UDP_Server() --- */static char cltBuf[UDP_BUF_SIZE];static char cltBufin[UDP_BUF_SIZE];/********************************************************************** UDP_Client() -- Test a UDP client application**** Description:**** Arguments:****** Returns:** 0 -- Successful execution** 1 -- Test failed.**** Notes:****
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -