예제 #1
0
파일: main.go 프로젝트: hycxa/gonet
//----------------------------------------------- handle cooldown request
func handleClient(conn *net.UDPConn) {
	// init receive buffer
	config := cfg.Get()
	maxchan, e := strconv.Atoi(config["stats_max_queue_size"])
	if e != nil {
		maxchan = DEFAULT_MAX_QUEUE
		log.Println("cannot parse stats_max_queue_size from config", e)
	}

	ch := make(chan []byte, maxchan)
	defer close(ch)

	go StatsAgent(ch, conn)

	// loop receiving
	for {
		// udp receive buffer, max 512 packet
		data := make([]byte, 512)
		n, addr, err := conn.ReadFromUDP(data)
		if err != nil {
			log.Println("read udp failed", n, addr, err)
			continue
		}

		ch <- data[:n]
	}
}
예제 #2
0
func (tunnel *Tunnel) HandleVOIPData(buff []byte, addr *net.UDPAddr, conn *net.UDPConn) {
	now := time.Now().Unix()

	_, receiver, _, err := tunnel.ReadVOIPData(buff)
	if err != nil {
		return
	}

	client := tunnel.FindClient(addr)
	if client == nil || client.appid == 0 {
		return
	}

	client.timestamp = now
	//转发消息
	other := tunnel.FindAppClient(client.appid, receiver)
	if other == nil {
		log.Infof("can't dispatch voip data sender:%d receiver:%d", client.uid, receiver)
		return
	}

	if other.has_header {
		buffer := new(bytes.Buffer)
		var h byte = VOIP_DATA
		buffer.WriteByte(h)
		buffer.Write(buff)
		data := buffer.Bytes()
		conn.WriteTo(data, other.addr)
	} else {
		data := buff
		conn.WriteTo(data, other.addr)
	}
}
예제 #3
0
파일: voice.go 프로젝트: 42wim/matterbridge
// udpKeepAlive sends a udp packet to keep the udp connection open
// This is still a bit of a "proof of concept"
func (v *VoiceConnection) udpKeepAlive(udpConn *net.UDPConn, close <-chan struct{}, i time.Duration) {

	if udpConn == nil || close == nil {
		return
	}

	var err error
	var sequence uint64

	packet := make([]byte, 8)

	ticker := time.NewTicker(i)
	for {

		binary.LittleEndian.PutUint64(packet, sequence)
		sequence++

		_, err = udpConn.Write(packet)
		if err != nil {
			v.log(LogError, "write error, %s", err)
			return
		}

		select {
		case <-ticker.C:
			// continue loop and send keepalive
		case <-close:
			return
		}
	}
}
예제 #4
0
func PutRecv(conn *net.UDPConn, context *UdpContext) int {
	file := context.file
	buffer := make([]byte, 1024)
	read, err := conn.Read(buffer)

	if err == io.EOF {
		break
	}

	if err != nil {
		fmt.Printf("Error reading from network: %s. Aborting transfer\n", err)
		return
	}

	_, err = file.Write(buffer[:read])
	if err != nil {
		fmt.Println("Error writing to file; aborting transfer")
		return
	}

	_, err = conn.Write([]byte("put-ack"))
	if err != nil {
		fmt.Println("Error writing ack; aborting transfer")
		return
	}

	return read
}
func listen(socket *net.UDPConn) {
	data := make([]byte, 4096)
	length, remoteAddr, err := socket.ReadFromUDP(data)
	if err != nil {
		log.Fatal(err)
	}

	//@ToDO: Check, if the user wants the file
	var request transmitFileRequest
	error := json.Unmarshal(data[:length], &request)
	if error != nil {
		log.Fatal(error)
	}

	fmt.Printf("Got connection attempt from %s -> ", remoteAddr)

	//Only accept connections from server when the user specified it
	if *server != nil {
		if remoteAddr.IP.Equal(*server) {
			fmt.Printf("accepting connection\n")
			fmt.Printf("Remote wants to transfer %s (Size: %s)\n", request.FileName, humanize.Bytes(uint64(request.Size)))
			acceptIncomingFileTransfer(remoteAddr.IP, request)
		} else {
			fmt.Printf("DENY (only accepting connections from %s)", *server)
		}
	} else {
		fmt.Printf("accepting connection\n")
		fmt.Printf("Remote wants to transfer %s (Size: %s)\n", request.FileName, humanize.Bytes(uint64(request.Size)))
		acceptIncomingFileTransfer(remoteAddr.IP, request)
	}
}
예제 #6
0
//发出缓存
func fushCache(conn *net.UDPConn, sendAddr *net.UDPAddr) {
	cacheArray := TempChanMap[sendAddr.IP.String()]

	/*    for item := cacheArray.Front();item != nil ; item = item.Next() {
	                fmt.Print("-");
			conn.WriteToUDP(item.Value.([]byte), sendAddr)
	    }
	*/
	length := TempChanMapIndex[sendAddr.IP.String()]
	fmt.Println(length, sendAddr.IP.String())
	for i := 0; i < length; i++ {
		if len(cacheArray[i]) > 0 {
			fmt.Print("-")
			position, err := conn.WriteToUDP(cacheArray[i], sendAddr)

			checkError(err)
			if err != nil {
				fmt.Println(position)
			}
		}
	}
	/*
	   for item := cacheArray.Front();item != nil ; item = item.Next() {
	      cacheArray.Remove(item)
	      fmt.Println("remove");
	   }
	*/
	TempChanMap[sendAddr.IP.String()] = make([][]byte, 1000, 1000000)
	TempChanMapIndex[sendAddr.IP.String()] = 0
	//fmt.Println(TempChanMap,sendAddr.IP.String());

}
// Loops indefinitely to read packets and update connection status.
func ListenForDsPackets(listener *net.UDPConn) {
	var data [50]byte
	for {
		listener.Read(data[:])
		dsStatus := decodeStatusPacket(data)

		// Update the status and last packet times for this alliance/team in the global struct.
		dsConn := mainArena.AllianceStations[dsStatus.AllianceStation].DsConn
		if dsConn != nil && dsConn.TeamId == dsStatus.TeamId {
			dsConn.DriverStationStatus = dsStatus
			dsConn.LastPacketTime = time.Now()
			if dsStatus.RobotLinked {
				dsConn.LastRobotLinkedTime = time.Now()
			}
			dsConn.SecondsSinceLastRobotLink = time.Since(dsConn.LastRobotLinkedTime).Seconds()
			dsConn.DriverStationStatus.MissedPacketCount -= dsConn.missedPacketOffset

			// Log the packet if the match is in progress.
			matchTimeSec := mainArena.MatchTimeSec()
			if matchTimeSec > 0 && dsConn.log != nil {
				dsConn.log.LogDsStatus(matchTimeSec, dsStatus)
			}
		}
	}
}
예제 #8
0
/**
  Handles a single UDP connection as a goroutine
*/
func udpHandler(buf []byte, b int, n int, conn *net.UDPConn, addr *net.UDPAddr) {
	defer fmt.Printf("Datagram %d sent!\n", n)

	// Slice buffer depending on read bytes, trim spaces
	clean := bytes.TrimSpace(buf[:b])

	// Decrypt incoming request []byte
	clean = decrypt(clean)

	// Parse the received JSON
	r := Request{}
	err := json.Unmarshal(clean, &r)
	if err != nil {
		fmt.Println(err)
		return
	}

	resp := findRoad(&r)

	// Convert to JSON, send over the wire
	s, err := json.Marshal(&resp)
	if err != nil {
		panic(err)
	}

	// Encrypt response []byte
	s = encrypt(s)

	conn.WriteToUDP(s, addr)
}
예제 #9
0
파일: server.go 프로젝트: thinkingo/wagl
// serveUDP starts a UDP listener for the server.
// Each request is handled in a separate goroutine.
func (srv *Server) serveUDP(l *net.UDPConn) error {
	defer l.Close()

	if srv.NotifyStartedFunc != nil {
		srv.NotifyStartedFunc()
	}

	reader := Reader(&defaultReader{srv})
	if srv.DecorateReader != nil {
		reader = srv.DecorateReader(reader)
	}

	handler := srv.Handler
	if handler == nil {
		handler = DefaultServeMux
	}
	rtimeout := srv.getReadTimeout()
	// deadline is not used here
	for {
		m, s, e := reader.ReadUDP(l, rtimeout)
		srv.lock.RLock()
		if !srv.started {
			srv.lock.RUnlock()
			return nil
		}
		srv.lock.RUnlock()
		if e != nil {
			continue
		}
		srv.inFlight.Add(1)
		go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
	}
}
예제 #10
0
func detect_precense(connection *net.UDPConn, masterChan chan bool) {
	buffer := make([]byte, 2048)
	for {
		t := time.Now()
		connection.SetReadDeadline(t.Add(3 * time.Second))
		_, _, err := connection.ReadFromUDP(buffer)
		if err != nil {
			fmt.Println("UDP timeout: ", err)
			masterChan <- true
			break
		}
		/*
			fmt.Println("I'm getting into this for")
			select {
			case <-time.After(time.Second * 3):
				fmt.Println("Master dead")
				masterChan <- true
				break L
				/*
					default:
						_, _, err := connection.ReadFromUDP(buffer)
						if err != nil {
							fmt.Println("You messed up in detect_precense.")
							panic(err)
						}
			}(*/
	}
}
예제 #11
0
파일: server.go 프로젝트: u-root/u-root
// Serve starts the server using an existing UDPConn.
func (s *Server) Serve(conn *net.UDPConn) error {
	if s.rh == nil && s.wh == nil {
		return ErrNoRegisteredHandlers
	}

	s.connMu.Lock()
	s.conn = conn
	s.connMu.Unlock()

	s.connMu.RLock()
	defer s.connMu.RUnlock()
	buf := make([]byte, 65536) // Largest possible TFTP datagram
	for {
		numBytes, addr, err := conn.ReadFromUDP(buf)
		if err != nil {
			if s.close {
				return nil
			}
			return wrapError(err, "reading from conn")
		}

		// Make a copy of the received data
		b := make([]byte, numBytes)
		copy(b, buf)

		switch buf[1] {
		case 1: //RRQ
			go s.dispatchReadRequest(addr, b)
		case 2: //WRQ
			go s.dispatchWriteRequest(addr, b)
		default:
			go s.demuxToConn(addr, b)
		}
	}
}
예제 #12
0
func (handler *VMessInboundHandler) handlePacket(conn *net.UDPConn, request *protocol.VMessRequest, packet v2net.Packet, clientAddr *net.UDPAddr) {
	ray := handler.vPoint.DispatchToOutbound(packet)
	close(ray.InboundInput())

	responseKey := md5.Sum(request.RequestKey)
	responseIV := md5.Sum(request.RequestIV)

	buffer := alloc.NewBuffer().Clear()
	defer buffer.Release()

	responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], buffer)
	if err != nil {
		log.Error("VMessIn: Failed to create encrypt writer: %v", err)
		return
	}
	responseWriter.Write(request.ResponseHeader)

	hasData := false

	if data, ok := <-ray.InboundOutput(); ok {
		hasData = true
		responseWriter.Write(data.Value)
		data.Release()
	}

	if hasData {
		conn.WriteToUDP(buffer.Value, clientAddr)
		log.Info("VMessIn sending %d bytes to %s", buffer.Len(), clientAddr.String())
	}
}
예제 #13
0
파일: router.go 프로젝트: adieu/weave
func (router *Router) udpReader(conn *net.UDPConn, po PacketSink) {
	defer conn.Close()
	dec := NewEthernetDecoder()
	handleUDPPacket := router.handleUDPPacketFunc(dec, po)
	buf := make([]byte, MaxUDPPacketSize)
	for {
		n, sender, err := conn.ReadFromUDP(buf)
		if err == io.EOF {
			return
		} else if err != nil {
			log.Println("ignoring UDP read error", err)
			continue
		} else if n < NameSize {
			continue // TODO something different?
		} else {
			name := PeerNameFromBin(buf[:NameSize])
			packet := make([]byte, n-NameSize)
			copy(packet, buf[NameSize:n])
			udpPacket := &UDPPacket{
				Name:   name,
				Packet: packet,
				Sender: sender}
			peerConn, found := router.Ourself.ConnectionTo(name)
			if !found {
				continue
			}
			relayConn, ok := peerConn.(*LocalConnection)
			if !ok {
				continue
			}
			checkWarn(relayConn.Decryptor.IterateFrames(handleUDPPacket, udpPacket))
		}
	}
}
예제 #14
0
파일: udp.go 프로젝트: frimkus/ttk4145-ex3
func udp_receive_server(lconn, bconn *net.UDPConn, message_size int, receive_ch chan Udp_message) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("ERROR in udp_receive_server: %s \n Closing connection.", r)
			lconn.Close()
			bconn.Close()
		}
	}()

	bconn_rcv_ch := make(chan Udp_message)
	lconn_rcv_ch := make(chan Udp_message)

	go udp_connection_reader(lconn, message_size, lconn_rcv_ch)
	go udp_connection_reader(bconn, message_size, bconn_rcv_ch)

	for {
		select {

		case buf := <-bconn_rcv_ch:
			receive_ch <- buf

		case buf := <-lconn_rcv_ch:
			receive_ch <- buf
		}
	}
}
예제 #15
0
파일: message.go 프로젝트: vonwenm/GoDHCP
func ReadMessage(c *net.UDPConn) (msg *Message, src net.Addr, err os.Error) {
	buff := make([]byte, DHCP_MAX_LEN)
	//log.Printf("Waiting for read")
	n, src, err := c.ReadFromUDP(buff)
	if err != nil {
		return
	}
	if n < DHCP_MIN_LEN {
		err = os.NewError("Invalid DHCP messge received (too small)")
		return
	}
	buff = buff[0:n]
	msg = &Message{
		Operation:    buff[0],
		HardwareType: buff[1],
		HardwareLen:  buff[2],
		Hops:         buff[3],
		Xid:          binary.LittleEndian.Uint32(buff[4:8]),
		Secs:         binary.LittleEndian.Uint16(buff[8:10]),
		Flags:        binary.LittleEndian.Uint16(buff[10:12]),
		ClientIP:     net.IPv4(buff[12], buff[13], buff[14], buff[15]),
		YourIP:       net.IPv4(buff[16], buff[17], buff[18], buff[19]),
		ServerIP:     net.IPv4(buff[20], buff[21], buff[22], buff[23]),
		GatewayIP:    net.IPv4(buff[24], buff[25], buff[26], buff[27]),
	}
	copy(msg.ClientHWAddr[0:16], buff[28:44])
	// We skip the magic bytes and assume for now.
	msg.Options, err = ParseOptions(buff[DHCP_MIN_LEN+4:])
	//log.Printf("Parsed %d options.", len(msg.Options))
	// TODO: Handle Option 52 extensions.
	return
}
예제 #16
0
func getFile(conn *net.UDPConn) *os.File {
	file, err := conn.File()
	if err != nil {
		log.Fatal(err)
	}
	return file
}
예제 #17
0
func messageServer(c *net.UDPConn, message string) {
	log.Printf("Write to server: %q", message)
	n, err := c.Write([]byte(message))
	if n == 0 || err != nil {
		log.Fatalf("WriteToUDP failed: %v", err.Error())
	}
}
예제 #18
0
func (d *UDPClient) sendAnnouncement(remote net.Addr, conn *net.UDPConn) bool {
	if debug {
		l.Debugf("discover %s: broadcast: Sending self announcement to %v", d.url, remote)
	}

	ann := d.announcer.Announcement()
	pkt, err := ann.MarshalXDR()
	if err != nil {
		return false
	}

	myID := protocol.DeviceIDFromBytes(ann.This.ID)

	_, err = conn.WriteTo(pkt, remote)
	if err != nil {
		if debug {
			l.Debugf("discover %s: broadcast: Failed to send self announcement: %s", d.url, err)
		}
		return false
	}

	// Verify that the announce server responds positively for our device ID

	time.Sleep(1 * time.Second)

	ann, err = d.Lookup(myID)
	if err != nil && debug {
		l.Debugf("discover %s: broadcast: Self-lookup failed: %v", d.url, err)
	} else if debug {
		l.Debugf("discover %s: broadcast: Self-lookup returned: %v", d.url, ann.This.Addresses)
	}
	return len(ann.This.Addresses) > 0
}
예제 #19
0
파일: client.go 프로젝트: rrawrriw/ite
func UDPInbox(ctx Context, conn *net.UDPConn, buf int) (chan UDPPacket, error) {
	udpIn := make(chan UDPPacket, buf)
	go func() {
		for {
			payload := make([]byte, MaxUDPPacketSize)

			size, rAddr, err := conn.ReadFromUDP(payload)
			if err != nil {
				// Check if the done channel closed then shutdown goroutine
				select {
				case <-ctx.DoneChan:
					ctx.Log.Debug.Println("UDPInbox shutdown")
					close(udpIn)
					return
				default:
					// Need default case otherwise the select statment would block
				}

				ctx.Log.Error.Println(err.Error())
				continue
			}
			ctx.Log.Debug.Println("Receive UDP Packet")
			udpIn <- UDPPacket{
				RemoteAddr: rAddr,
				Size:       size,
				Payload:    payload,
			}

		}

	}()
	return udpIn, nil
}
예제 #20
0
파일: api.go 프로젝트: Wikia/influxdb
func (s *Server) HandleSocket(socket *net.UDPConn) {
	// From https://collectd.org/wiki/index.php/Binary_protocol
	//   1024 bytes (payload only, not including UDP / IP headers)
	//   In versions 4.0 through 4.7, the receive buffer has a fixed size
	//   of 1024 bytes. When longer packets are received, the trailing data
	//   is simply ignored. Since version 4.8, the buffer size can be
	//   configured. Version 5.0 will increase the default buffer size to
	//   1452 bytes (the maximum payload size when using UDP/IPv6 over
	//   Ethernet).
	buffer := make([]byte, 1452)

	for {
		n, _, err := socket.ReadFromUDP(buffer)
		if err != nil || n == 0 {
			log.Error("Collectd ReadFromUDP error: %s", err)
			continue
		}

		packets, err := collectd.Packets(buffer[:n], s.typesdb)
		if err != nil {
			log.Error("Collectd parse error: %s", err)
			continue
		}

		for _, packet := range *packets {
			series := packetToSeries(&packet)
			err = s.coordinator.WriteSeriesData(s.user, s.database, series)
			if err != nil {
				log.Error("Collectd cannot write data: %s", err)
				continue
			}
		}
	}
}
예제 #21
0
파일: tftp.go 프로젝트: evanqi/TFTP
/* Constructs and sends an ACK packet over conn. */
func sendAck(conn *net.UDPConn, addr *net.UDPAddr) {
	ack := make([]byte, 4)
	copy(ack, ACK)
	//TODO copy block number
	_, err := conn.WriteToUDP(ack, addr)
	checkError(err)
}
예제 #22
0
파일: krpc.go 프로젝트: kissthink/dht
// Read from UDP socket, writes slice of byte into channel.
func readFromSocket(socket *net.UDPConn, conChan chan packetType, bytesArena arena, stop chan bool) {
	for {
		b := bytesArena.Pop()
		n, addr, err := socket.ReadFromUDP(b)
		if err != nil {
			log.V(3).Infof("DHT: readResponse error:", err)
		}
		b = b[0:n]
		if n == maxUDPPacketSize {
			log.V(3).Infof("DHT: Warning. Received packet with len >= %d, some data may have been discarded.\n", maxUDPPacketSize)
		}
		totalReadBytes.Add(int64(n))
		if n > 0 && err == nil {
			p := packetType{b, *addr}
			select {
			case conChan <- p:
				continue
			case <-stop:
				return
			}
		}
		// Do a non-blocking read of the stop channel and stop this goroutine if the channel
		// has been closed.
		select {
		case <-stop:
			return
		default:
		}
	}
}
예제 #23
0
파일: tftp.go 프로젝트: evanqi/TFTP
/* Sends file data in DATA packets over conn. */
func sendData(conn *net.UDPConn, addr *net.UDPAddr, filename string) {
	input, err := os.Open(filename)
	checkError(err)

	buf := make([]byte, 512)
	for {
		n, err := input.Read(buf)
		checkError(err)

		data := make([]byte, n+4)
		copy(data, DATA)
		copy(data[4:], buf[:n])
		_, err = conn.WriteToUDP(data, addr)
		checkError(err)

		if n < len(buf) {
			finalAck := make([]byte, 4)
			for !bytes.Equal(finalAck[0:2], ACK) {
				_, _, err := conn.ReadFromUDP(finalAck)
				checkError(err)
			}

			break
		}
	}

}
예제 #24
0
func GetSend(conn *net.UDPConn, context *UdpContext) {
	file := context.file
	buffer := make([]byte, 1024)
	// Read into buffer
	len, err := file.Read(buffer)

	if len > 0 {
		// Write to socket
		_, err = conn.WriteTo(buffer[:len], context.dest)
		if err != nil {
			log.Println("Failed to write data to socket; abandoning transfer")
		}
	}

	// EOF?
	if err == io.EOF {
		log.Println("Transfer completed")
		return
	}

	// Some other error
	if err != nil {
		log.Println("Error reading file; abandoning transfer")
		return
	}
}
예제 #25
0
func (tunnel *Tunnel) HandleAuth(buff []byte, addr *net.UDPAddr, conn *net.UDPConn) {
	now := time.Now().Unix()
	token, err := tunnel.ReadVOIPAuth(buff)
	if err != nil {
		return
	}
	client := tunnel.FindClient(addr)
	if client == nil {
		//首次收到认证消息
		client = &TunnelClient{appid: 0, uid: 0, addr: addr, timestamp: now, has_header: true, token: token}
		tunnel.AuthClient(client, token)
		return
	} else if client.token == token {
		//认证成功
		t := make([]byte, 2)
		t[0] = VOIP_AUTH_STATUS
		t[1] = 0
		conn.WriteTo(t, addr)
		client.timestamp = now
		log.Infof("tunnel auth appid:%d uid:%d", client.appid, client.uid)
	} else {
		//新的token
		tunnel.RemoveTunnelClient(client)
		client.token = token
		client.appid = 0
		client.uid = 0
		client.timestamp = now
		tunnel.AuthClient(client, token)
	}
}
예제 #26
0
// serveUDP starts a UDP listener for the server.
// Each request is handled in a separate goroutine.
func (srv *Server) serveUDP(l *net.UDPConn) error {
	defer l.Close()

	if srv.NotifyStartedFunc != nil {
		srv.NotifyStartedFunc()
	}

	handler := srv.Handler
	if handler == nil {
		handler = DefaultServeMux
	}
	rtimeout := srv.getReadTimeout()
	// deadline is not used here
	for {
		m, s, e := srv.readUDP(l, rtimeout)
		select {
		case <-srv.stopUDP:
			return nil
		default:
		}
		if e != nil {
			continue
		}
		srv.wgUDP.Add(1)
		go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
	}
	panic("dns: not reached")
}
예제 #27
0
func (local *localNode) Run(terminate <-chan bool) (err error) {
	var conn *net.UDPConn
	// Main loop for LocalPeer's activity.
	// (Listening to replies and requests.)

	conn, err = net.ListenUDP("udp4", &net.UDPAddr{
		IP:   net.IPv4(0, 0, 0, 0),
		Port: local.Port,
	})
	if err != nil {
		return
	}

	local.Connection = conn

	rpcTerminate := make(chan bool)
	go func() {
		local.rpcListenLoop(rpcTerminate)
	}()

	go func() {
		<-terminate

		close(rpcTerminate)
		conn.Close()

	}()

	return
}
예제 #28
0
파일: udp.go 프로젝트: NinjaOSX/v2ray-core
func (server *SocksServer) AcceptPackets(conn *net.UDPConn) error {
	for {
		buffer := alloc.NewBuffer()
		nBytes, addr, err := conn.ReadFromUDP(buffer.Value)
		if err != nil {
			log.Error("Socks failed to read UDP packets: %v", err)
			buffer.Release()
			continue
		}
		log.Info("Client UDP connection from %v", addr)
		request, err := protocol.ReadUDPRequest(buffer.Value[:nBytes])
		buffer.Release()
		if err != nil {
			log.Error("Socks failed to parse UDP request: %v", err)
			request.Data.Release()
			continue
		}
		if request.Fragment != 0 {
			log.Warning("Dropping fragmented UDP packets.")
			// TODO handle fragments
			request.Data.Release()
			continue
		}

		udpPacket := v2net.NewPacket(request.Destination(), request.Data, false)
		log.Info("Send packet to %s with %d bytes", udpPacket.Destination().String(), request.Data.Len())
		go server.handlePacket(conn, udpPacket, addr, request.Address)
	}
}
예제 #29
0
func read(serv_conn *net.UDPConn) {

	buffer := make([]byte, 1024)
	// number of last received packet
	var last_recd int = 0
	for {
		//		fmt.Println("Reading from UDP buffer...")
		n, addr, err := serv_conn.ReadFromUDP(buffer)

		// get the current packet number
		current_packet, err := strconv.Atoi(string(buffer[0:n]))
		CheckError(err)
		// check the packet we have now against the one we received last
		go check_packet(serv_conn, current_packet, last_recd)
		last_recd, err = strconv.Atoi(string(buffer[0:n]))
		// check for duplicates and discard them as necessary, otherwise mark as received
		if last_recd == most_recent {
			fmt.Println("Duplicate packet found, discarding", string(buffer[0:n]))
		} else {
			fmt.Println("Successfully received", string(buffer[0:n]), "from", addr)
			most_recent = last_recd
		}
		CheckError(err)
	}
}
예제 #30
-1
func udpListener(conn *net.UDPConn, sendingFrom net.Addr, start *sync.WaitGroup, end *sync.WaitGroup) {
	fmt.Fprintln(os.Stderr, "Started listener...")
	start.Done()

	buff := make([]byte, 1600) // standard MTU size -- no packet should be bigger
	for i := 0; true; i++ {
		fmt.Fprintln(os.Stderr, "Waiting for packet #"+strconv.Itoa(i))
		len, from, err := conn.ReadFromUDP(buff)
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error receiving UDP packet: "+err.Error())
		}
		if from.String() == sendingFrom.String() {
			i--
			continue
		}

		str := string(buff[:len])
		fmt.Println("Received message from " + from.String() + "\n\t" + str)
		if strings.Contains(str, "<<terminate>>") {
			conn.Close()
			fmt.Fprintln(os.Stderr, "Terminated UDP listener")
			end.Done()
			return
		}
	}
}