// NewClient creates, initiates, and returns a new client. This function // should return after a connection with the server has been established // (i.e., the client has received an Ack message from the server in response // to its connection request), and should return a non-nil error if a // connection could not be made (i.e., if after K epochs, the client still // hasn't received an Ack message from the server in response to its K // connection requests). // // hostport is a colon-separated string identifying the server's host address // and port number (i.e., "localhost:9999"). func NewClient(hostport string, params *Params) (Client, error) { if params == nil { params = &Params{5, 2000, 1} } addr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return nil, err } conn, err := lspnet.DialUDP("udp", nil, addr) if err != nil { return nil, err } c := &client{ comm: NewCommon(addr, params), connUDP: conn, readBufToAppChan: make(chan *Message), netToReadWinChan: make(chan *Message), epochToReadWinChan: make(chan *Message), appToWriteBufChan: make(chan *Message), netToWriteBufChan: make(chan *Message), epochToWriteBufChan: make(chan *Message), connChan: make(chan *Message), appCloseSynChan: make(chan bool, 1), netLostCloseSynChan: make(chan bool, 1), } // go c.manageReceivedMsg() go c.handleEpoch() go c.readFromServer() go c.handleReadSlideWindow() go c.handleWriteSlideWindow() //init lock // c.connIDSynChan <- 0 c.appCloseSynChan <- false c.netLostCloseSynChan <- false //start connect c.writeToServer(c.generateMsg(MsgConnect, 0, nil)) connMsg := <-c.connChan if connMsg.Type == MsgAck && connMsg.SeqNum == 0 { SetValueToIntChan(c.comm.connIDSynChan, connMsg.ConnID) SetValueToBoolChan(c.comm.isConnectedSynChan, true) c.comm.connID = connMsg.ConnID fmt.Println("Client:", c.comm.connID, "Start") return c, nil } return nil, errors.New("Connection failed") }
// dial the remote server using the hostport given, used on client side func (h *networkUtility) dial(hostport string) error { serverAddr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return err } conn, err := lspnet.DialUDP("udp", nil, serverAddr) if err != nil { return err } h.conn = conn return nil }
func (now *Connect) dial(hostport string) error { serverAddr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return err } conn, err := lspnet.DialUDP("udp", nil, serverAddr) if err != nil { return err } now.addr = serverAddr now.conn = conn return nil }
func (c *client) StartDial(hostport string) error { var err error c.sAddr, err = lspnet.ResolveUDPAddr("udp", hostport) if err != nil { fmt.Println("Unable to resolve server UDP addr ", hostport) return err } go c.handleMessages() go c.ticking() c.conn, err = lspnet.DialUDP("udp", nil, c.sAddr) if err != nil { fmt.Println("cannot dial to port ", hostport) return err } fmt.Println("dial to ", hostport) // send connect message c.writeChan <- clientWriteData{MsgConnect, 0, nil} // waiting for connect ack buf := make([]byte, 2000) msg := Message{} n, err := c.conn.Read(buf) if err != nil { fmt.Println("unable read from connection") msg = <-c.connSucChan } else { json.Unmarshal(buf[0:n], &msg) } switch msg.Type { case MsgAck: c.setidChan <- msg.ConnID default: return errors.New("unable to connect") } // start listen on data/ack go c.StartListen() return nil }
func NewFixedSizeUDPClient(maxMsgSize int, serverHostPort string) (UDPClient, error) { serverAddr, err := net.ResolveUDPAddr("udp4", serverHostPort) if err != nil { return nil, err } // non-blocking. it won't wait for server to build connection as TCP does // it returns non-nil error even though the server is not running. (no connection) conn, err := net.DialUDP("udp", nil, serverAddr) if err != nil { return nil, err } return &FixedSizeUDPClient{ maxMsgSize: maxMsgSize, serverAddr: serverAddr, conn: conn, closed: false, }, nil }
// NewClient creates, initiates, and returns a new client. This function // should return after a connection with the server has been established // (i.e., the client has received an Ack message from the server in response // to its connection request), and should return a non-nil error if a // connection could not be made (i.e., if after K epochs, the client still // hasn't received an Ack message from the server in response to its K // connection requests). // // hostport is a colon-separated string identifying the server's host address // and port number (i.e., "localhost:9999"). func NewClient(hostport string, params *Params) (Client, error) { c := &client{ nextSN: 1, writeToServerChan: make(chan *Message), readFromServerChan: make(chan *Message), readRequest: &requestRead{ ask: make(chan int), response: make(chan *Message), }, writeRequest: &requestWrite{ ask: make(chan []byte), response: make(chan error), }, readMap: make(map[int]*Message), // write list has order writeMap: make(map[int]*Message), connected: make(chan int), flag: false, connect: false, // variables for window size windowSize: params.WindowSize, // send to client data nextSmallestAck: 1, mapAck: make(map[int]bool), mapNeedAck: make(map[int]*Message), // receive from client data nextSmallestData: 1, // TODO: didn't need this mapAcked: make(map[int]bool), mapReceived: make(map[int]*Message), nextDataRead: 1, // epoch variables epochChan: make(chan int), epochMillis: params.EpochMillis, epochLimit: params.EpochLimit, epochNum: 0, lostConn: false, // clsoe closeRequest: &requestClose{ ask: make(chan int), //response: 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), } // connect to server addr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return nil, err } conn, err := lspnet.DialUDP("udp", nil, addr) if err != nil { return nil, err } fmt.Println("new client") c.conn = conn c.addr = addr fmt.Println("70") ////fmt.Println("74") go c.readMessage() go c.handleMessage() go c.epochFire() msg := NewConnect() c.writeToServerChan <- msg <-c.connected //fmt.Println("Client 156: connect success") return c, nil }
// NewClient creates, initiates, and returns a new client. This function // should return after a connection with the server has been established // (i.e., the client has received an Ack message from the server in response // to its connection request), and should return a non-nil error if a // connection could not be made (i.e., if after K epochs, the client still // hasn't received an Ack message from the server in response to its K // connection requests). // // hostport is a colon-separated string identifying the server's host address // and port number (i.e., "localhost:9999"). func NewClient(hostport string, params *Params) (Client, error) { c := &client{ hostport: hostport, params: params, connID: -1, seqNum: 0, conn: nil, connected: false, connOpen: make(chan struct{}), connClose: make(chan struct{}), connMsg: NewConnect(), dataMsgTo: make(chan *Message), dataMsgFr: make(chan *Message), dataMsgTokens: make(chan struct{}, params.WindowSize), seqNumToActChan: make(chan map[int]*Activity), seqNumToAckMsgChan: make(chan map[int]*Message), dataWrWindow: make(chan *SlideWindow, 1), dataRdWindow: make(chan *SlideWindow, 1), } raddr, err := lspnet.ResolveUDPAddr("udp", hostport) if err != nil { return nil, err } conn, err := lspnet.DialUDP("udp", nil, raddr) if err != nil { return nil, err } c.conn = conn c.dataWrWindow <- &SlideWindow{ seqNumLower: 1, seqNumUpper: 1 + c.params.WindowSize, } c.dataRdWindow <- &SlideWindow{ seqNumLower: 1, seqNumUpper: 1 + c.params.WindowSize, } go c.onWrite() go c.onRead() go c.epoch() go c.connect() for { select { case <-c.connOpen: c.connected = true return c, nil case <-c.connClose: c.connected = false return nil, errors.New("connection not yet established") } } return nil, errors.New("not yet implemented") }