nsprpub/pr/tests/udpsrv.c

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*******************************************************************
michael@0 7 ** udpsrc.c -- Test basic function of UDP server
michael@0 8 **
michael@0 9 ** udpsrv operates on the same machine with program udpclt.
michael@0 10 ** udpsrv is the server side of a udp sockets application.
michael@0 11 ** udpclt is the client side of a udp sockets application.
michael@0 12 **
michael@0 13 ** The test is designed to assist developers in porting/debugging
michael@0 14 ** the UDP socket functions of NSPR.
michael@0 15 **
michael@0 16 ** This test is not a stress test.
michael@0 17 **
michael@0 18 ** main() starts two threads: UDP_Server() and UDP_Client();
michael@0 19 ** main() uses PR_JoinThread() to wait for the threads to complete.
michael@0 20 **
michael@0 21 ** UDP_Server() does repeated recvfrom()s from a socket.
michael@0 22 ** He detects an EOF condition set by UDP_Client(). For each
michael@0 23 ** packet received by UDP_Server(), he checks its content for
michael@0 24 ** expected content, then sends the packet back to UDP_Client().
michael@0 25 **
michael@0 26 ** UDP_Client() sends packets to UDP_Server() using sendto()
michael@0 27 ** he recieves packets back from the server via recvfrom().
michael@0 28 ** After he sends enough packets containing UDP_AMOUNT_TO_WRITE
michael@0 29 ** bytes of data, he sends an EOF message.
michael@0 30 **
michael@0 31 ** The test issues a pass/fail message at end.
michael@0 32 **
michael@0 33 ** Notes:
michael@0 34 ** The variable "_debug_on" can be set to 1 to cause diagnostic
michael@0 35 ** messages related to client/server synchronization. Useful when
michael@0 36 ** the test hangs.
michael@0 37 **
michael@0 38 ** Error messages are written to stdout.
michael@0 39 **
michael@0 40 ********************************************************************
michael@0 41 */
michael@0 42 /* --- include files --- */
michael@0 43 #include "nspr.h"
michael@0 44 #include "prpriv.h"
michael@0 45
michael@0 46 #include "plgetopt.h"
michael@0 47 #include "prttools.h"
michael@0 48
michael@0 49 #include <stdio.h>
michael@0 50 #include <stdlib.h>
michael@0 51 #include <string.h>
michael@0 52 #include <errno.h>
michael@0 53
michael@0 54 #ifdef XP_PC
michael@0 55 #define mode_t int
michael@0 56 #endif
michael@0 57
michael@0 58 #define UDP_BUF_SIZE 4096
michael@0 59 #define UDP_DGRAM_SIZE 128
michael@0 60 #define UDP_AMOUNT_TO_WRITE (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1)
michael@0 61 #define NUM_UDP_CLIENTS 1
michael@0 62 #define NUM_UDP_DATAGRAMS_PER_CLIENT 5
michael@0 63 #define UDP_SERVER_PORT 9050
michael@0 64 #define UDP_CLIENT_PORT 9053
michael@0 65 #define MY_INADDR PR_INADDR_ANY
michael@0 66 #define PEER_INADDR PR_INADDR_LOOPBACK
michael@0 67
michael@0 68 #define UDP_TIMEOUT 400000
michael@0 69 /* #define UDP_TIMEOUT PR_INTERVAL_NO_TIMEOUT */
michael@0 70
michael@0 71 /* --- static data --- */
michael@0 72 static PRIntn _debug_on = 0;
michael@0 73 static PRBool passed = PR_TRUE;
michael@0 74 static PRUint32 cltBytesRead = 0;
michael@0 75 static PRUint32 srvBytesRead = 0;
michael@0 76 static PRFileDesc *output = NULL;
michael@0 77
michael@0 78 /* --- static function declarations --- */
michael@0 79 #define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg)
michael@0 80
michael@0 81
michael@0 82
michael@0 83 /*******************************************************************
michael@0 84 ** ListNetAddr() -- Display the Net Address on stdout
michael@0 85 **
michael@0 86 ** Description: displays the component parts of a PRNetAddr struct
michael@0 87 **
michael@0 88 ** Arguments: address of PRNetAddr structure to display
michael@0 89 **
michael@0 90 ** Returns: void
michael@0 91 **
michael@0 92 ** Notes:
michael@0 93 **
michael@0 94 ********************************************************************
michael@0 95 */
michael@0 96 void ListNetAddr( char *msg, PRNetAddr *na )
michael@0 97 {
michael@0 98 char mbuf[256];
michael@0 99
michael@0 100 sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n",
michael@0 101 msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) );
michael@0 102 #if 0
michael@0 103 DPRINTF( mbuf );
michael@0 104 #endif
michael@0 105 } /* --- end ListNetAddr() --- */
michael@0 106
michael@0 107 /********************************************************************
michael@0 108 ** UDP_Server() -- Test a UDP server application
michael@0 109 **
michael@0 110 ** Description: The Server side of a UDP Client/Server application.
michael@0 111 **
michael@0 112 ** Arguments: none
michael@0 113 **
michael@0 114 ** Returns: void
michael@0 115 **
michael@0 116 ** Notes:
michael@0 117 **
michael@0 118 **
michael@0 119 ********************************************************************
michael@0 120 */
michael@0 121 static void PR_CALLBACK UDP_Server( void *arg )
michael@0 122 {
michael@0 123 static char svrBuf[UDP_BUF_SIZE];
michael@0 124 PRFileDesc *svrSock;
michael@0 125 PRInt32 rv;
michael@0 126 PRNetAddr netaddr;
michael@0 127 PRBool bound = PR_FALSE;
michael@0 128 PRBool endOfInput = PR_FALSE;
michael@0 129 PRInt32 numBytes = UDP_DGRAM_SIZE;
michael@0 130
michael@0 131 DPRINTF("udpsrv: UDP_Server(): starting\n" );
michael@0 132
michael@0 133 /* --- Create the socket --- */
michael@0 134 DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" );
michael@0 135 svrSock = PR_NewUDPSocket();
michael@0 136 if ( svrSock == NULL )
michael@0 137 {
michael@0 138 passed = PR_FALSE;
michael@0 139 if (debug_mode)
michael@0 140 PR_fprintf(output,
michael@0 141 "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" );
michael@0 142 return;
michael@0 143 }
michael@0 144
michael@0 145 /* --- Initialize the sockaddr_in structure --- */
michael@0 146 memset( &netaddr, 0, sizeof( netaddr ));
michael@0 147 netaddr.inet.family = PR_AF_INET;
michael@0 148 netaddr.inet.port = PR_htons( UDP_SERVER_PORT );
michael@0 149 netaddr.inet.ip = PR_htonl( MY_INADDR );
michael@0 150
michael@0 151 /* --- Bind the socket --- */
michael@0 152 while ( !bound )
michael@0 153 {
michael@0 154 DPRINTF("udpsrv: UDP_Server(): Binding socket\n" );
michael@0 155 rv = PR_Bind( svrSock, &netaddr );
michael@0 156 if ( rv < 0 )
michael@0 157 {
michael@0 158 if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
michael@0 159 {
michael@0 160 if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
michael@0 161 PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
michael@0 162 PR_Sleep( PR_MillisecondsToInterval( 2000 ));
michael@0 163 continue;
michael@0 164 }
michael@0 165 else
michael@0 166 {
michael@0 167 passed = PR_FALSE;
michael@0 168 if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
michael@0 169 PR_Bind(): failed: %ld with error: %ld\n",
michael@0 170 rv, PR_GetError() );
michael@0 171 PR_Close( svrSock );
michael@0 172 return;
michael@0 173 }
michael@0 174 }
michael@0 175 else
michael@0 176 bound = PR_TRUE;
michael@0 177 }
michael@0 178 ListNetAddr( "UDP_Server: after bind", &netaddr );
michael@0 179
michael@0 180 /* --- Recv the socket --- */
michael@0 181 while( !endOfInput )
michael@0 182 {
michael@0 183 DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" );
michael@0 184 rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
michael@0 185 if ( rv == -1 )
michael@0 186 {
michael@0 187 passed = PR_FALSE;
michael@0 188 if (debug_mode)
michael@0 189 PR_fprintf(output,
michael@0 190 "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n",
michael@0 191 PR_GetError() );
michael@0 192 PR_Close( svrSock );
michael@0 193 return;
michael@0 194 }
michael@0 195 ListNetAddr( "UDP_Server after RecvFrom", &netaddr );
michael@0 196
michael@0 197 srvBytesRead += rv;
michael@0 198
michael@0 199 if ( svrBuf[0] == 'E' )
michael@0 200 {
michael@0 201 DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" );
michael@0 202 endOfInput = PR_TRUE;
michael@0 203 }
michael@0 204
michael@0 205 /* --- Send the socket --- */
michael@0 206 DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" );
michael@0 207 rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT );
michael@0 208 if ( rv == -1 )
michael@0 209 {
michael@0 210 passed = PR_FALSE;
michael@0 211 if (debug_mode)
michael@0 212 PR_fprintf(output,
michael@0 213 "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n",
michael@0 214 PR_GetError() );
michael@0 215 PR_Close( svrSock );
michael@0 216 return;
michael@0 217 }
michael@0 218 ListNetAddr( "UDP_Server after SendTo", &netaddr );
michael@0 219 }
michael@0 220
michael@0 221 /* --- Close the socket --- */
michael@0 222 DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
michael@0 223 rv = PR_Close( svrSock );
michael@0 224 if ( rv != PR_SUCCESS )
michael@0 225 {
michael@0 226 passed = PR_FALSE;
michael@0 227 if (debug_mode)
michael@0 228 PR_fprintf(output,
michael@0 229 "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" );
michael@0 230 return;
michael@0 231 }
michael@0 232
michael@0 233 DPRINTF("udpsrv: UDP_Server(): Normal end\n" );
michael@0 234 } /* --- end UDP_Server() --- */
michael@0 235
michael@0 236
michael@0 237 static char cltBuf[UDP_BUF_SIZE];
michael@0 238 static char cltBufin[UDP_BUF_SIZE];
michael@0 239 /********************************************************************
michael@0 240 ** UDP_Client() -- Test a UDP client application
michael@0 241 **
michael@0 242 ** Description:
michael@0 243 **
michael@0 244 ** Arguments:
michael@0 245 **
michael@0 246 **
michael@0 247 ** Returns:
michael@0 248 ** 0 -- Successful execution
michael@0 249 ** 1 -- Test failed.
michael@0 250 **
michael@0 251 ** Notes:
michael@0 252 **
michael@0 253 **
michael@0 254 ********************************************************************
michael@0 255 */
michael@0 256 static void PR_CALLBACK UDP_Client( void *arg )
michael@0 257 {
michael@0 258 PRFileDesc *cltSock;
michael@0 259 PRInt32 rv;
michael@0 260 PRBool bound = PR_FALSE;
michael@0 261 PRNetAddr netaddr;
michael@0 262 PRNetAddr netaddrx;
michael@0 263 PRBool endOfInput = PR_FALSE;
michael@0 264 PRInt32 numBytes = UDP_DGRAM_SIZE;
michael@0 265 PRInt32 writeThisMany = UDP_AMOUNT_TO_WRITE;
michael@0 266 int i;
michael@0 267
michael@0 268
michael@0 269 DPRINTF("udpsrv: UDP_Client(): starting\n" );
michael@0 270
michael@0 271 /* --- Create the socket --- */
michael@0 272 cltSock = PR_NewUDPSocket();
michael@0 273 if ( cltSock == NULL )
michael@0 274 {
michael@0 275 passed = PR_FALSE;
michael@0 276 if (debug_mode)
michael@0 277 PR_fprintf(output,
michael@0 278 "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" );
michael@0 279 return;
michael@0 280 }
michael@0 281
michael@0 282 /* --- Initialize the sockaddr_in structure --- */
michael@0 283 memset( &netaddr, 0, sizeof( netaddr ));
michael@0 284 netaddr.inet.family = PR_AF_INET;
michael@0 285 netaddr.inet.ip = PR_htonl( MY_INADDR );
michael@0 286 netaddr.inet.port = PR_htons( UDP_CLIENT_PORT );
michael@0 287
michael@0 288 /* --- Initialize the write buffer --- */
michael@0 289 for ( i = 0; i < UDP_BUF_SIZE ; i++ )
michael@0 290 cltBuf[i] = i;
michael@0 291
michael@0 292 /* --- Bind the socket --- */
michael@0 293 while ( !bound )
michael@0 294 {
michael@0 295 DPRINTF("udpsrv: UDP_Client(): Binding socket\n" );
michael@0 296 rv = PR_Bind( cltSock, &netaddr );
michael@0 297 if ( rv < 0 )
michael@0 298 {
michael@0 299 if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
michael@0 300 {
michael@0 301 if (debug_mode)
michael@0 302 PR_fprintf(output,
michael@0 303 "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
michael@0 304 PR_Sleep( PR_MillisecondsToInterval( 2000 ));
michael@0 305 continue;
michael@0 306 }
michael@0 307 else
michael@0 308 {
michael@0 309 passed = PR_FALSE;
michael@0 310 if (debug_mode)
michael@0 311 PR_fprintf(output,
michael@0 312 "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n",
michael@0 313 rv, PR_GetError() );
michael@0 314 PR_Close( cltSock );
michael@0 315 return;
michael@0 316 }
michael@0 317 }
michael@0 318 else
michael@0 319 bound = PR_TRUE;
michael@0 320 }
michael@0 321 ListNetAddr( "UDP_Client after Bind", &netaddr );
michael@0 322
michael@0 323 /* --- Initialize the sockaddr_in structure --- */
michael@0 324 memset( &netaddr, 0, sizeof( netaddr ));
michael@0 325 netaddr.inet.family = PR_AF_INET;
michael@0 326 netaddr.inet.ip = PR_htonl( PEER_INADDR );
michael@0 327 netaddr.inet.port = PR_htons( UDP_SERVER_PORT );
michael@0 328
michael@0 329 /* --- send and receive packets until no more data left */
michael@0 330 while( !endOfInput )
michael@0 331 {
michael@0 332 /*
michael@0 333 ** Signal EOF in the data stream on the last packet
michael@0 334 */
michael@0 335 if ( writeThisMany <= UDP_DGRAM_SIZE )
michael@0 336 {
michael@0 337 DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" );
michael@0 338 cltBuf[0] = 'E';
michael@0 339 endOfInput = PR_TRUE;
michael@0 340 }
michael@0 341
michael@0 342 /* --- SendTo the socket --- */
michael@0 343 if ( writeThisMany > UDP_DGRAM_SIZE )
michael@0 344 numBytes = UDP_DGRAM_SIZE;
michael@0 345 else
michael@0 346 numBytes = writeThisMany;
michael@0 347 writeThisMany -= numBytes;
michael@0 348 {
michael@0 349 char mbuf[256];
michael@0 350 sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n",
michael@0 351 writeThisMany, numBytes );
michael@0 352 DPRINTF( mbuf );
michael@0 353 }
michael@0 354
michael@0 355 DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" );
michael@0 356 rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
michael@0 357 if ( rv == -1 )
michael@0 358 {
michael@0 359 passed = PR_FALSE;
michael@0 360 if (debug_mode)
michael@0 361 PR_fprintf(output,
michael@0 362 "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n",
michael@0 363 PR_GetError() );
michael@0 364 PR_Close( cltSock );
michael@0 365 return;
michael@0 366 }
michael@0 367 ListNetAddr( "UDP_Client after SendTo", &netaddr );
michael@0 368
michael@0 369 /* --- RecvFrom the socket --- */
michael@0 370 memset( cltBufin, 0, UDP_BUF_SIZE );
michael@0 371 DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" );
michael@0 372 rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT );
michael@0 373 if ( rv == -1 )
michael@0 374 {
michael@0 375 passed = PR_FALSE;
michael@0 376 if (debug_mode) PR_fprintf(output,
michael@0 377 "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n",
michael@0 378 PR_GetError() );
michael@0 379 PR_Close( cltSock );
michael@0 380 return;
michael@0 381 }
michael@0 382 ListNetAddr( "UDP_Client after RecvFrom()", &netaddr );
michael@0 383 cltBytesRead += rv;
michael@0 384
michael@0 385 /* --- verify buffer --- */
michael@0 386 for ( i = 0; i < rv ; i++ )
michael@0 387 {
michael@0 388 if ( cltBufin[i] != i )
michael@0 389 {
michael@0 390 /* --- special case, end of input --- */
michael@0 391 if ( endOfInput && i == 0 && cltBufin[0] == 'E' )
michael@0 392 continue;
michael@0 393 passed = PR_FALSE;
michael@0 394 if (debug_mode) PR_fprintf(output,
michael@0 395 "udpsrv: UDP_Client(): return data mismatch\n" );
michael@0 396 PR_Close( cltSock );
michael@0 397 return;
michael@0 398 }
michael@0 399 }
michael@0 400 if (debug_mode) PR_fprintf(output, ".");
michael@0 401 }
michael@0 402
michael@0 403 /* --- Close the socket --- */
michael@0 404 DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
michael@0 405 rv = PR_Close( cltSock );
michael@0 406 if ( rv != PR_SUCCESS )
michael@0 407 {
michael@0 408 passed = PR_FALSE;
michael@0 409 if (debug_mode) PR_fprintf(output,
michael@0 410 "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" );
michael@0 411 return;
michael@0 412 }
michael@0 413 DPRINTF("udpsrv: UDP_Client(): ending\n" );
michael@0 414 } /* --- end UDP_Client() --- */
michael@0 415
michael@0 416 /********************************************************************
michael@0 417 ** main() -- udpsrv
michael@0 418 **
michael@0 419 ** arguments:
michael@0 420 **
michael@0 421 ** Returns:
michael@0 422 ** 0 -- Successful execution
michael@0 423 ** 1 -- Test failed.
michael@0 424 **
michael@0 425 ** Description:
michael@0 426 **
michael@0 427 ** Standard test case setup.
michael@0 428 **
michael@0 429 ** Calls the function UDP_Server()
michael@0 430 **
michael@0 431 ********************************************************************
michael@0 432 */
michael@0 433
michael@0 434 int main(int argc, char **argv)
michael@0 435 {
michael@0 436 PRThread *srv, *clt;
michael@0 437 /* The command line argument: -d is used to determine if the test is being run
michael@0 438 in debug mode. The regress tool requires only one line output:PASS or FAIL.
michael@0 439 All of the printfs associated with this test has been handled with a if (debug_mode)
michael@0 440 test.
michael@0 441 Usage: test_name -d -v
michael@0 442 */
michael@0 443 PLOptStatus os;
michael@0 444 PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
michael@0 445 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
michael@0 446 {
michael@0 447 if (PL_OPT_BAD == os) continue;
michael@0 448 switch (opt->option)
michael@0 449 {
michael@0 450 case 'd': /* debug mode */
michael@0 451 debug_mode = 1;
michael@0 452 break;
michael@0 453 case 'v': /* verbose mode */
michael@0 454 _debug_on = 1;
michael@0 455 break;
michael@0 456 default:
michael@0 457 break;
michael@0 458 }
michael@0 459 }
michael@0 460 PL_DestroyOptState(opt);
michael@0 461
michael@0 462 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
michael@0 463 PR_STDIO_INIT();
michael@0 464 output = PR_STDERR;
michael@0 465
michael@0 466 PR_SetConcurrency(4);
michael@0 467
michael@0 468 /*
michael@0 469 ** Create the Server thread
michael@0 470 */
michael@0 471 DPRINTF( "udpsrv: Creating Server Thread\n" );
michael@0 472 srv = PR_CreateThread( PR_USER_THREAD,
michael@0 473 UDP_Server,
michael@0 474 (void *) 0,
michael@0 475 PR_PRIORITY_LOW,
michael@0 476 PR_LOCAL_THREAD,
michael@0 477 PR_JOINABLE_THREAD,
michael@0 478 0 );
michael@0 479 if ( srv == NULL )
michael@0 480 {
michael@0 481 if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
michael@0 482 passed = PR_FALSE;
michael@0 483 }
michael@0 484
michael@0 485 /*
michael@0 486 ** Give the Server time to Start
michael@0 487 */
michael@0 488 DPRINTF( "udpsrv: Pausing to allow Server to start\n" );
michael@0 489 PR_Sleep( PR_MillisecondsToInterval(200) );
michael@0 490
michael@0 491 /*
michael@0 492 ** Create the Client thread
michael@0 493 */
michael@0 494 DPRINTF( "udpsrv: Creating Client Thread\n" );
michael@0 495 clt = PR_CreateThread( PR_USER_THREAD,
michael@0 496 UDP_Client,
michael@0 497 (void *) 0,
michael@0 498 PR_PRIORITY_LOW,
michael@0 499 PR_LOCAL_THREAD,
michael@0 500 PR_JOINABLE_THREAD,
michael@0 501 0 );
michael@0 502 if ( clt == NULL )
michael@0 503 {
michael@0 504 if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
michael@0 505 passed = PR_FALSE;
michael@0 506 }
michael@0 507
michael@0 508 /*
michael@0 509 **
michael@0 510 */
michael@0 511 DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" );
michael@0 512 PR_JoinThread( srv );
michael@0 513 PR_JoinThread( clt );
michael@0 514
michael@0 515 /*
michael@0 516 ** Evaluate test results
michael@0 517 */
michael@0 518 if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \
michael@0 519 srvBytesRead(%ld), expected(%ld)\n",
michael@0 520 cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE );
michael@0 521 if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE )
michael@0 522 {
michael@0 523 passed = PR_FALSE;
michael@0 524 }
michael@0 525 PR_Cleanup();
michael@0 526 if ( passed )
michael@0 527 return 0;
michael@0 528 else
michael@0 529 return 1;
michael@0 530 } /* --- end main() --- */

mercurial