Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
LocalServerUDP/LocalServerUDPClient/UDPClientSample.cp
/* |
File: TCPPitchSample.cp |
Contains: Tcp pitch sample. |
Copyright: © 1993-1997, 2000 by Apple Computer, Inc., all rights reserved. |
*/ |
// OT TCP Pitch Test Program (as an SIOW app) |
#include <OpenTransport.h> |
#include <OpenTransportProviders.h> |
#include <Processes.h> |
#include <stdio.h> |
#include <StdLib.h> |
#include "ServerInfo.h" |
#include <AppleEvents.h> |
#ifndef T_DISCON_IND |
#define T_DISCON_IND 128 |
#endif |
/******************************************************************************* |
** GLOBAL VARIABLES |
********************************************************************************/ |
InetPort gCatchPort = 0; |
InetHost gCatchIpAddr = 0; |
InetPort gPitchPort = 0; |
InetHost gPitchIpAddr = 0; |
unsigned short gBindCompleted = 0; |
unsigned short gCallRcvOrdDiscon = 0; |
static OTNotifyUPP gNotifier = nil; |
struct InetAddress gCatchAddr; |
/******************************************************************************* |
** Function Prototypes |
********************************************************************************/ |
void Inits(); |
OSErr GetServerInfo(); |
void CleanUp(); |
void Idle(); |
void DoIt(); |
OSErr FindProcessBySignature( const OSType targetType, |
const OSType targetCreator, |
ProcessSerialNumberPtr psnPtr ); |
OTResult SetFourByteOption(EndpointRef ep, |
OTXTILevel level, |
OTXTIName name, |
UInt32 value); |
/******************************************************************************* |
** main function |
********************************************************************************/ |
void main() |
{ |
printf ("Hello World\n"); |
Inits(); |
if (GetServerInfo() == noErr) |
{ |
DoIt(); |
} |
else |
printf ("GetServerInfo returned an error\n"); |
CleanUp(); |
} |
/******************************************************************************* |
** Initialize Quickdraw and ASLM |
********************************************************************************/ |
void Inits() |
{ |
if (InitOpenTransport() != kOTNoError) |
{ |
fprintf(stderr, "OTTcpPitch: Could not initialize ASLM, exiting\n"); |
exit(1); |
} |
} |
/******************************************************************************* |
The FindProcessBySignature function returns a ProcessSerialNumber |
for a process whose signature (type and creator) matches the input values. |
The ProcessSerialNumber will be kNoProcess is the requested process cannot |
be found. |
targetType input: The file type of the process to be found. |
targetCreator input: The creator type of the process to be found. |
psnPtr input: Pointer to a ProcessSerialNumber where the |
process serial number is returned. |
output: Process serial number. |
RESULT CODES |
____________ |
noErr 0 No error |
procNotFound Ð600 No eligible process with specified descriptor |
____________ |
********************************************************************************/ |
OSErr FindProcessBySignature( const OSType targetType, |
const OSType targetCreator, |
ProcessSerialNumberPtr psnPtr ) |
{ |
OSErr anErr = noErr; |
Boolean foundTheProcess = false; |
ProcessInfoRec infoRec; |
infoRec.processInfoLength = sizeof( ProcessInfoRec ); |
infoRec.processName = nil; |
infoRec.processLocation = nil; |
infoRec.processAppSpec = nil; |
psnPtr->lowLongOfPSN = kNoProcess; |
psnPtr->highLongOfPSN = kNoProcess; |
while ( !foundTheProcess && (anErr == noErr) ) |
{ |
anErr = GetNextProcess( psnPtr ); |
if ( anErr == noErr ) |
{ |
anErr = GetProcessInformation( psnPtr, &infoRec ); |
if ( ( anErr == noErr ) |
&& ( infoRec.processType == targetType ) |
&& ( infoRec.processSignature == targetCreator ) ) |
{ |
foundTheProcess = true; |
} |
} |
} |
return anErr; |
}//end FindProcessBySignature |
/******************************************************************************* |
** Send an Apple Event to find out if the server is up and running |
** which will return the address to send the event to |
********************************************************************************/ |
OSErr GetServerInfo() |
{ |
AppleEvent reqEvent = { typeNull, nil }; |
AppleEvent retEvent = { typeNull, nil }; |
DescType typeCode; |
OSErr err; |
ProcessSerialNumber psn = { kNoProcess, kNoProcess }; |
AEDesc targetAppDesc = { typeNull, nil }; |
Size size; |
char mystr[255]; |
UInt32 dummy; |
err = FindProcessBySignature(kApplicationFileType, kPassServerSignature, &psn); |
if (err == noErr) |
{ |
err = AECreateDesc (typeProcessSerialNumber, &psn, sizeof( ProcessSerialNumber ), &targetAppDesc); |
if ( err == noErr ) |
{ |
err = AECreateAppleEvent( kPassServerInfoClass, kPassServerInfoEvent, &targetAppDesc, |
kAutoGenerateReturnID, kAnyTransactionID, &reqEvent); |
if (err) |
printf("AECreateAppleEvent returned error %d\n", err); |
} |
else |
printf("AECreateDesc returned error %d\n", err); |
AEDisposeDesc( &targetAppDesc ); |
} |
else |
printf("FindProcessBySignature returned error %d\n", err); |
if (err == noErr) |
{ |
// we have to insert a dummy in the outgoing AppleEvent list which the |
// LocalServer is expecting, but will not do anything with. Just doing this |
// for kicks |
err = AEPutParamPtr(&reqEvent, keyDirectObject, typeLongInteger, &dummy, |
sizeof(dummy) ); |
} |
if (err == noErr) |
{ |
err = AESend(&reqEvent, &retEvent, kAEWaitReply+kAENeverInteract, kAENormalPriority, |
kAEDefaultTimeout, nil, nil); |
if (err != noErr) |
{ |
printf("Error calling AESend = %d\n", err); |
} |
else |
{ |
// get the apple event object |
err = AEGetParamPtr(&retEvent, keyDirectObject, kPassServerType, &typeCode, |
&gCatchAddr, sizeof (struct InetAddress), &size ); |
if (err != noErr) |
printf("Error calling AEGetParamDesc to get the catch address %d\n", err); |
// dispose of the returned apple event |
AEDisposeDesc(&retEvent); |
} |
AEDisposeDesc(&reqEvent); |
} |
if (err == noErr) |
{ |
OTInetHostToString(gCatchAddr.fHost, mystr); |
printf("LocalServer found at %s, port %d.\n", mystr, gCatchAddr.fPort); |
} |
return err; |
} |
/******************************************************************************* |
** Clean up at the end |
********************************************************************************/ |
void CleanUp() |
{ |
CloseOpenTransport(); |
} |
/******************************************************************************* |
** Idle |
********************************************************************************/ |
void Idle() |
{ |
EventRecord theEvent; |
WaitNextEvent(everyEvent, &theEvent, 1, nil); |
} |
/******************************************************************************* |
** EventHandler |
********************************************************************************/ |
pascal void EventHandler(void*, OTEventCode event, OTResult, void*) |
{ |
OTEventCode tempevent = 0; |
switch ( event ) |
{ |
case T_BINDCOMPLETE: |
gBindCompleted = 1; |
break; |
case T_DATA: |
printf("T_DATA event occurred\n"); |
break; |
case T_ERROR: |
printf("T_ERROR event occurred\n"); |
break; |
default: |
printf("TCP EventHandler got unexpected event %d", event); |
break; |
} |
return; |
} |
/******************************************************************************* |
** DoIt |
********************************************************************************/ |
void DoIt() |
{ |
TEndpoint* ep = NULL; |
TEndpointInfo info; |
struct InetAddress rcvsin, reqsin, retsin; |
TBind req, ret; |
TUnitData sendunitdata, rcvunitdata; |
OSStatus err = kOTNoError; |
OTResult result; |
long myport = 0; |
char mystr[255]; |
OTFlags flags = 0; |
OTTimeStamp time; |
OTTimeStamp end, begin, diff; |
UInt32 diffInMsec; |
UInt32 i, j; |
UInt8 *ptr; |
myport = 0; |
gPitchPort =(InetPort) myport; |
gPitchIpAddr = gCatchAddr.fHost; |
OTMemset(&rcvsin, 0, sizeof(struct InetAddress)); |
OTMemset(&reqsin, 0, sizeof(struct InetAddress)); |
OTMemset(&rcvsin, 0, sizeof(struct InetAddress)); |
OTMemset(&req, 0, sizeof(TBind)); |
OTMemset(&ret, 0, sizeof(TBind)); |
do |
{ |
// |
// Now create a TCP |
// |
ep = OTOpenEndpoint(OTCreateConfiguration(kUDPName), 0, &info, &err); |
if ( ep == NULL || err != kOTNoError ) |
{ |
ep = NULL; |
fprintf(stderr,"ERROR: OpenEndpoint(\"UDP\") failed with %d\n", err); |
break; |
} |
err = ep->SetSynchronous(); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: SetSynchronous() failed with %d\n", err); |
break; |
} |
// |
// Install notifier we're going to use for testing |
// |
gNotifier = NewOTNotifyUPP(EventHandler); |
err = ep->InstallNotifier(gNotifier, 0); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err); |
break; |
} |
// |
// Try to bind |
// |
gPitchIpAddr = 0; |
OTInitInetAddress(&reqsin, gPitchPort, gPitchIpAddr); |
req.addr.len = sizeof(struct InetAddress); |
req.addr.buf = (unsigned char *) &reqsin; |
req.qlen = 0; // don't care for udp |
ret.addr.maxlen = sizeof(struct InetAddress); |
ret.addr.buf = (unsigned char *) &retsin; |
OTInetHostToString(retsin.fHost, mystr); |
printf("Trying to bind at %s, port %d.\n", mystr, gPitchPort); |
// bind TCP to current address and port |
err = ep->Bind(&req, &ret); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: Bind() failed with %d\n", err); |
break; |
} |
OTInetHostToString(retsin.fHost, mystr); |
printf("Bound ep to %s, port %d.\n", mystr, retsin.fPort); |
err = ep->SetSynchronous(); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: SetSynchronous() failed with %d\n", err); |
break; |
} |
for (i = 0; i < 50; i++) |
{ |
OTGetTimeStamp(&time); |
sendunitdata.addr.len = sizeof(struct InetAddress); |
sendunitdata.addr.buf = (UInt8*) &gCatchAddr; |
sendunitdata.opt.len = 0; |
sendunitdata.opt.buf = 0; |
sendunitdata.udata.len = sizeof(time); |
sendunitdata.udata.buf = (UInt8*)&time; |
rcvunitdata.addr.maxlen = sizeof(struct InetAddress); |
rcvunitdata.addr.buf = (UInt8*) &rcvsin; |
rcvunitdata.opt.maxlen = 0; |
rcvunitdata.opt.buf = 0; |
rcvunitdata.udata.maxlen = sizeof(time); |
rcvunitdata.udata.len = 0; |
// set address of "begin" as the buffer to return the OTTimeStamp in |
rcvunitdata.udata.buf = (UInt8*)&begin; |
err = ep->SndUData(&sendunitdata); |
if ( err == kOTNoError) |
{ |
// the server will return the byte sent |
result = ep->RcvUData(&rcvunitdata, &flags); |
// get a timestamp |
OTGetTimeStamp(&end); |
fprintf(stderr, "Sent bytes: <%d> data\n", sendunitdata.udata.len); |
// print out the bytes of the time stamp |
if (result == kOTNoError) |
{ |
fprintf(stderr, "Rcv'd nbytes: <%d> data\n", rcvunitdata.udata.len); |
// "begin" should contain the original time stamp |
OTSubtractTimeStamps(&diff, &begin, &end); |
diffInMsec = OTTimeStampInMilliseconds(&diff); |
printf("%ld bytes received - %ld milliseconds\n", rcvunitdata.udata.len, diffInMsec); |
ptr = (UInt8*) &begin; |
for (j = 0; j < rcvunitdata.udata.len; j++) |
fprintf(stderr, "%X ", *ptr++); |
fprintf(stderr, "\n"); |
} |
else |
fprintf(stderr, "OTRcvUData error %d\n", result); |
} |
else |
{ |
fprintf(stderr, "ERROR: Snd() failed with %d\n", err); |
break; |
} |
Idle(); |
fflush(stderr); |
} |
} while (false); |
if ( ep != NULL ) |
{ |
err = ep->SetSynchronous(); |
// |
// Remove notifier |
// |
ep->RemoveNotifier(); |
// |
// Try to Unbind |
// |
err = ep->Unbind(); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: Unbind() returned %d\n", err); |
} |
// |
// Get rid of endpoint. |
// |
err = OTCloseProvider(ep); |
if ( err != kOTNoError ) |
{ |
fprintf(stderr, "ERROR: CloseEndpoint() failed with %d\n", err); |
} |
} |
fprintf(stderr, "Bye\n"); |
} |
OTResult SetFourByteOption(EndpointRef ep, |
OTXTILevel level, |
OTXTIName name, |
UInt32 value) |
{ |
OTResult err; |
TOption option; |
TOptMgmt request; |
TOptMgmt result; |
/* Set up the option buffer to specify the option and value to |
set. */ |
option.len = kOTFourByteOptionSize; |
option.level= level; |
option.name = name; |
option.status = 0; |
option.value[0] = value; |
/* Set up request parameter for OTOptionManagement */ |
request.opt.buf= (UInt8 *) &option; |
request.opt.len= sizeof(option); |
request.flags = T_NEGOTIATE; |
/* Set up reply parameter for OTOptionManagement. */ |
result.opt.buf = (UInt8 *) &option; |
result.opt.maxlen = sizeof(option); |
err = OTOptionManagement(ep, &request, &result); |
if (err == noErr) { |
if (option.status != T_SUCCESS) |
err = option.status; |
} |
return (err); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30