// listen to incoming UDP data using the given hostport, used on server side func (h *networkUtility) listen(hostport string) error { serverAddr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return nil } conn, err := lspnet.ListenUDP("udp", serverAddr) if err != nil { return err } h.conn = conn return nil }
func (now *Connect) listen(hostport string) error { serverAddr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return nil } conn, err := lspnet.ListenUDP("udp", serverAddr) if err != nil { return err } now.conn = conn now.addr = serverAddr return nil }
func (s *server) StartListen(port string) error { uAddr, err := lspnet.ResolveUDPAddr("udp", ":"+port) if err != nil { fmt.Println("Unable to resolve UDP addr ", port) return err } s.sConn, err = lspnet.ListenUDP("udp", uAddr) if err != nil { fmt.Println("Unable to listen on port ", port) return err } go s.handleMessages() go s.ticking() for { select { case <-s.quitAllChan: fmt.Println("server quit listener") return nil default: // read a msg from UDP and check its type buf := make([]byte, 2000) n, addr, err := s.sConn.ReadFromUDP(buf) if err != nil { return err } msg := Message{} json.Unmarshal(buf[0:n], &msg) switch msg.Type { case MsgConnect: // receive a conn msg from client s.addChan <- addr case MsgData: // add to data channel if hash match, drop otherwise if hex.EncodeToString(calMD5Hash(msg)) == hex.EncodeToString(msg.Hash) { s.dataChan <- &msg } else { fmt.Println("Hash does not match") } case MsgAck: s.ackChan <- &msg } } } return err }
func NewFixedSizeUDPServer(maxMsgSize int, port int) (UDPServer, error) { addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf(":%v", port)) if err != nil { return nil, err } conn, err := net.ListenUDP("udp", addr) // non-blocking. no need to wait for any client to establish a connection like TCP does if err != nil { return nil, err } return &FixedSizeUDPServer{ maxMsgSize: maxMsgSize, addr: addr, conn: conn, closed: false, }, nil }
// NewServer creates, initiates, and returns a new server. This function should // NOT block. Instead, it should spawn one or more goroutines (to handle things // like accepting incoming client connections, triggering epoch events at // fixed intervals, synchronizing events using a for-select loop like you saw in // project 0, etc.) and immediately return. It should return a non-nil error if // there was an error resolving or listening on the specified port number. func NewServer(port int, params *Params) (Server, error) { s := &server{ nextConnectId: 1, clients: make(map[int]*abstractClient), readFromClientChan: make(chan *msgPackage), writeToClientChan: make(chan *Message), readRequest: &requestRead{ ask: make(chan int), response: make(chan *Message), }, writeRequest: &requestWrite{ ask: make(chan []byte), connId: make(chan int), response: make(chan error), }, readList: list.New(), writeList: list.New(), flag: false, // variables for window size windowSize: params.WindowSize, mapNeedSend: list.New(), // variables for epoch epochChan: make(chan int), epochMillis: params.EpochMillis, epochLimit: params.EpochLimit, // close deleteClient: make(chan int), closeConnRequest: &requestCloseConn{ ask: make(chan int), getError: make(chan error), }, waitToWriteFinish: false, writeFinished: make(chan int), waitToAckFinish: false, ackFinished: make(chan int), closeRead: make(chan int, 1), closeEpoch: make(chan int, 1), closeEvent: make(chan int, 1), // close conn closeConn: make(chan int, 1), } // start server addr, err := lspnet.ResolveUDPAddr("udp", "localhost:"+strconv.Itoa(port)) if err != nil { return nil, err } conn, err := lspnet.ListenUDP("udp", addr) if err != nil { return nil, err } s.conn = conn go s.readMessage() go s.handleMessage() go s.epochFire() fmt.Println("new server") return s, nil }