summaryrefslogtreecommitdiff
path: root/comm/Datagram.cc
diff options
context:
space:
mode:
authorchatty1993-04-07 11:50:31 +0000
committerchatty1993-04-07 11:50:31 +0000
commitba066c34dde204aa192d03a23a81356374d93731 (patch)
tree39391f6235d2cf8a59a0634ac5ea430cdd21f5d4 /comm/Datagram.cc
parent05ab076e1c2a9ca16472f9a6b47b8d22914b3783 (diff)
downloadivy-league-ba066c34dde204aa192d03a23a81356374d93731.zip
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.gz
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.bz2
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.xz
Initial revision
Diffstat (limited to 'comm/Datagram.cc')
-rw-r--r--comm/Datagram.cc166
1 files changed, 166 insertions, 0 deletions
diff --git a/comm/Datagram.cc b/comm/Datagram.cc
new file mode 100644
index 0000000..b88deb5
--- /dev/null
+++ b/comm/Datagram.cc
@@ -0,0 +1,166 @@
+/*
+ * The Unix Channel
+ *
+ * by Michel Beaudouin-Lafon
+ *
+ * Copyright 1990-1993
+ * Laboratoire de Recherche en Informatique (LRI)
+ *
+ * Datagrams
+ *
+ * $Id$
+ * $CurLog$
+ */
+
+#include "Datagram.h"
+#include "MsgBuffer.h"
+#include <stdlib.h>
+#include <sys/socket.h>
+
+/*?class UchDatagram
+A datagram socket can send to and receive from any other datagram socket,
+unless it is connected.
+Thus, establishing a datagram connection is simple.
+
+UchDatagram sockets are not reliable: messages can be lost, duplicated, or be received in a different order.
+They keep the message boundaries: when \var{n} bytes are written, you will read at most \var{n} bytes;
+but if you ask to read less than \var{n} bytes, then the end of the message will be lost.
+
+When a datagram socket is not connected, you must provide an address when you send a message;
+when a message is read, the address of the sender can be retrieved (with function \fun{From}).
+When a datagram socket is connected, messages can only be sent to and read from the
+connected address. The \fun{Read} and \fun{Write} calls can be used in this case.
+
+Before any data can be sent or received, the socket must be set up with \fun{Setup}.
+?*/
+
+/*?nextdoc?*/
+UchDatagram :: UchDatagram ()
+: UchSocket (),
+ FAddr (0)
+{
+}
+
+/*?
+These constructors are similar to those of the class \typ{UchSocket}.
+?*/
+UchDatagram :: UchDatagram (UchAddress* bound, UchAddress* connected)
+: UchSocket (bound, connected),
+ FAddr (0)
+{
+}
+
+/*?nodoc?*/
+UchDatagram :: UchDatagram (const UchDatagram& d)
+: UchSocket (d),
+ FAddr (d.FAddr)
+{
+}
+
+/*?nodoc?*/
+UchDatagram :: ~UchDatagram ()
+{
+}
+
+#ifdef DOC
+/*?
+Return the address of the sender of the last received message.
+?*/
+UchAddress*
+UchDatagram :: From ()
+{ }
+
+#endif /* DOC */
+
+/*?nodoc?*/
+UchChannel*
+UchDatagram :: Copy () const
+{
+ return new UchDatagram (*this);
+}
+
+/*?nodoc?*/
+int
+UchDatagram :: SockType ()
+{
+ return SOCK_DGRAM;
+}
+
+/*?
+Send \var{len} bytes of \var{buf} on the datagram, to a destination address \var{to}.
+Return the number of bytes actually transferred, or -1 if a system error occurred.
+If the datagram is connected, you must use \fun{Write} instead.
+?*/
+int
+UchDatagram :: Send (byte* buf, int len, UchAddress& to)
+{
+ return sendto (FilDes (), (char*) buf, len, 0, to.GetSockAddr (), to.Length ());
+}
+
+/*?
+Receive at most \var{len} bytes into \var{buf}.
+Return the number of bytes actually transferred, or -1 if a system error occurred.
+The address of the sender can be retrieved with \fun{From}.
+If the socket is connected, you must use \fun{Read} instead.
+?*/
+int
+UchDatagram :: Receive (byte* buf, int len)
+{
+ GEN_ADDR addr;
+ int alen = sizeof (addr);
+ int ret;
+
+ ret = recvfrom (FilDes (), (char*) buf, len, 0, &addr.sa, &alen);
+ if (ret < 0)
+ return ret;
+
+ FAddr = UchAddress::Decode (&addr, alen);
+ return ret;
+}
+
+/*?
+This is equivalent to \fun{Send(buf, len, From ())}:
+it sends \fun{len} bytes to the sender of the last received message.
+If there is no such sender, it returns -1.
+?*/
+int
+UchDatagram :: Reply (byte* buf, int len)
+{
+ if (! FAddr)
+ return -1;
+ return sendto (FilDes (), (char*) buf, len, 0, FAddr->GetSockAddr (), FAddr->Length ());
+}
+
+/*?nextdoc?*/
+int
+UchDatagram :: Send (UchMsgBuffer& buf, UchAddress& to, bool peek)
+{
+ int n = Send (buf.Buffer (), buf.BufLength (), to);
+ if (! peek)
+ buf.Flush (n);
+ return n;
+}
+
+/*?nextdoc?*/
+int
+UchDatagram :: Receive (UchMsgBuffer& buf)
+{
+ int n = Receive (buf.Free (), buf.FreeLength ());
+ if (n > 0)
+ buf.More (n);
+ return n;
+}
+
+/*?
+The same functions but with a \typ{UchMsgBuffer} argument instead of a byte pointer and size.
+As usual, if \var{peek} is TRUE the buffer is not flushed.
+?*/
+int
+UchDatagram :: Reply (UchMsgBuffer& buf, bool peek)
+{
+ int n = Reply (buf.Buffer (), buf.BufLength ());
+ if (! peek)
+ buf.Flush (n);
+ return n;
+}
+