DatagramSocketTest.mesa
Copyright Ó 1991 by Xerox Corporation. All rights reserved.
Demers, November 22, 1988 12:12:47 pm PST
Carl Hauser, November 22, 1988 3:10:00 pm PST
Willie-s, August 13, 1991 4:24 pm PDT
Michael Plass, November 22, 1991 4:51 pm PST
DIRECTORY
Arpa,
ArpaUDP,
Basics,
Convert,
DatagramSocket,
IO,
Process,
RefText,
Rope,
UXIO
;
DatagramSocketTest: CEDAR PROGRAM
IMPORTS DatagramSocket, UXIO, IO, Convert, Rope, Basics, Process, RefText
~ {
SH: TYPE ~ DatagramSocket.Handle;
Address: TYPE ~ Arpa.Address;
Port: TYPE ~ ArpaUDP.Port;
Err: ERROR [code: ATOM] ¬ DatagramSocket.Error;
sh1: SH ¬ NIL;
a1: Address ¬ Arpa.nullAddress;
p1: Port ¬ ArpaUDP.nullPort;
sh2: SH ¬ NIL;
a2: Address ¬ Arpa.nullAddress;
p2: Port ¬ ArpaUDP.nullPort;
maxDatagramSize: CARD ¬ 0;
maxPrintLength: CARD ¬ 30;
sendData: Rope.ROPE ¬ "Hello. What hath God wrought?\nThe explorer was frozen in his big kayak just after making some queer discoveries.\nThe quick brown fox jumps over the lazy dog.\n";
stdout: IO.STREAM ¬ UXIO.CreateStandardStream[output];
PutErr: PROC [code: ATOM] ~ {
IO.PutF1[stdout, "Err[%g] - aborting\n", [atom[code]]];
};
Create: PROC ~ {
ENABLE Err => { PutErr[code]; CONTINUE };
sh1 ¬ DatagramSocket.Create[];
IO.PutRope[stdout, "First create succeeds ... "];
[a1, p1] ¬ DatagramSocket.GetLocal[sh1];
IO.PutF[stdout, "address: %g, port: %g\n", [rope[Convert.RopeFromArpaAddress[a1]]], [cardinal[Basics.Card16FromH[p1]]] ];
sh2 ¬ DatagramSocket.Create[];
IO.PutRope[stdout, "Second create succeeds ... "];
[a2, p2] ¬ DatagramSocket.GetLocal[sh2];
IO.PutF[stdout, "address: %g, port: %g\n", [rope[Convert.RopeFromArpaAddress[a2]]], [cardinal[Basics.Card16FromH[p2]]] ];
maxDatagramSize ¬ DatagramSocket.GetMaxDatagramSize[sh2];
IO.PutF1[stdout, "max datagram size: %g\n", [cardinal[maxDatagramSize]] ];
IF maxDatagramSize > 2048 THEN {
IO.PutRope[stdout, "(setting maxDatagramSize ← 2048)\n"];
maxDatagramSize ¬ 2048;
};
};
ForkCreate: PROC ~ TRUSTED { Process.Detach[ FORK Create[] ] };
Destroy: PROC ~ {
ENABLE Err => { PutErr[code]; CONTINUE };
IF sh1 # NIL THEN { DatagramSocket.Destroy[sh1]; sh1 ¬ NIL };
IF sh2 # NIL THEN { DatagramSocket.Destroy[sh2]; sh2 ¬ NIL };
IO.PutRope[stdout, "destroyed\n"];
};
ForkDestroy: PROC ~ TRUSTED { Process.Detach[ FORK Destroy[] ] };
Recv: PROC [timeoutMsec: CARD, unsafe: BOOL ¬ FALSE] ~ {
ENABLE Err => { PutErr[code]; CONTINUE };
recvBuf: REF TEXT ¬ RefText.New[maxDatagramSize];
fromA: Address;
fromP: Port;
nBytesRead: NAT;
IF unsafe
THEN TRUSTED {
[nBytesRead, fromA, fromP] ¬ DatagramSocket.UnsafeRecv[h~sh2, b~[LOOPHOLE[recvBuf, POINTER TO Basics.RawBytes]+UNITS[TEXT[0]], 0, recvBuf.maxLength], timeoutMsec~timeoutMsec];
recvBuf.length ¬ nBytesRead;
}
ELSE {
[nBytesRead, fromA, fromP] ¬ DatagramSocket.Recv[h~sh2, b~recvBuf, timeoutMsec~timeoutMsec];
};
IO.PutF[stdout, "Received %g bytes from %g : %g\n", [cardinal[nBytesRead]], [rope[Convert.RopeFromArpaAddress[fromA]]], [cardinal[Basics.Card16FromH[fromP]]] ];
IF recvBuf.length <= maxPrintLength THEN {
IO.PutF1[stdout, "data: %g\n", [rope[Rope.FromRefText[recvBuf]]] ];
};
};
ForkRecv: PROC ~ TRUSTED { Process.Detach[ FORK Recv[1000, FALSE] ] };
ForkRecvLongTimeout: PROC ~ TRUSTED { Process.Detach[ FORK Recv[10000, FALSE] ] };
ForkUnsafeRecv: PROC ~ TRUSTED { Process.Detach[ FORK Recv[1000, TRUE] ] };
ForkUnsafeRecvLongTimeout: PROC ~ TRUSTED { Process.Detach[ FORK Recv[10000, TRUE] ] };
Send: PROC [nBytes: NAT, unsafe: BOOL ¬ FALSE] ~ {
ENABLE Err => { PutErr[code]; CONTINUE };
sendBuf: REF TEXT ¬ Rope.ToRefText[sendData];
IF unsafe
THEN TRUSTED {
nBytes ¬ MIN[sendBuf.length, nBytes];
DatagramSocket.UnsafeSend[sh1, a2, p2,
[ LOOPHOLE[sendBuf, LONG POINTER TO Basics.RawBytes]+UNITS[TEXT[0]], 0, nBytes ]
];
}
ELSE {
nBytes ¬ MIN[nBytes, sendBuf.maxLength];
DatagramSocket.Send[sh1, a2, p2, sendBuf, 0, nBytes];
};
IO.PutF1[stdout, "Sent %g bytes\n", [cardinal[nBytes]] ];
};
ForkSend: PROC ~ TRUSTED { Process.Detach[ FORK Send[maxPrintLength, FALSE] ] };
ForkUnsafeSend: PROC ~ TRUSTED { Process.Detach[ FORK Send[maxPrintLength, TRUE] ] };
ForkSendLong: PROC ~ TRUSTED { Process.Detach[ FORK Send[maxDatagramSize, FALSE] ] };
ForkUnsafeSendLong: PROC ~ TRUSTED { Process.Detach[ FORK Send[maxDatagramSize, TRUE] ] };
}.