func NewSender(mcastAddress string) (*Sender, error) { var err error sender := new(Sender) // One connection is used both to send multicasts and to receive command packets. // We create the connection by setting up listening for commands packets, // but can also use the connection to send multicasts. sender.conn, err = utils.ListenUDP4() if err != nil { return nil, err } sender.mcast, err = net.ResolveUDPAddr("udp4", mcastAddress) if err != nil { return nil, err } minAgeSeconds := int32(10) maxAgeSeconds := int32(20) maxPayloadMB := uint32(50) sender.history = history.NewHistory(minAgeSeconds, maxAgeSeconds, maxPayloadMB) commands := make(chan packet.Packet, 10) go packet.Listen(sender.conn, commands) go sender.serveCommand(commands) return sender, nil }
func NewReceiver(mcastAddress string) (*Receiver, error) { receiver := new(Receiver) addr, err := net.ResolveUDPAddr("udp4", mcastAddress) if err != nil { return nil, err } receiver.messageConn, err = net.ListenMulticastUDP("udp4", nil, addr) if err != nil { return nil, err } receiver.controlConn, err = utils.ListenUDP4() if err != nil { receiver.messageConn.Close() return nil, err } // Currently there is just one channel that delivers all messages as they are received. // TODO: // 1. Track unique senders // 2. Track sequence numbers of packets from each sender // 3. Detect dropped packets and send request for packet resend to correct sender. // 4. Detect duplicate packets and drop them. // 5. Optionally hold future packets for delivery in correct sequence. receiver.senders = sendersmap.New() receiver.incoming = make(chan packet.Packet, 10) receiver.sequenced = make(chan packet.Packet, 10) go receiver.AnalyzeAndSequence() go packet.Listen(receiver.messageConn, receiver.incoming) return receiver, nil }