Beispiel #1
0
func (t *tcpClient) enqueue(chunk []byte) error {
	cchunk := C.CString(string(chunk))
	defer C.free(unsafe.Pointer(cchunk))

	sleepTime := time.Millisecond * 5

	for j := 0; j < maxEnqueueAttempts; j++ {
		err_t := C.tcp_write(t.client.pcb, unsafe.Pointer(cchunk), C.uint16_t(len(chunk)), 1)
		if err_t == C.ERR_OK {
			return nil
		}

		if err_t == C.ERR_MEM {
			// Could not enqueue anymore, let's flush and try again.
			err_t := C.tcp_output(t.client.pcb)
			if err_t == C.ERR_OK {
				// Last part was flushed, now continue and try again...
				time.Sleep(sleepTime)
				if sleepTime < maxWaitingTime {
					sleepTime = sleepTime * 2
				}
				continue
			}
			return fmt.Errorf("tcp_output: %d", int(err_t))
		}
	}

	return fmt.Errorf("Could not flush data. Giving up.")
}
Beispiel #2
0
func (t *tcpClient) flush() error {
	for {
		blen := t.outbuf.Len()

		if blen > writeBufSize {
			blen = writeBufSize
		}

		if blen == 0 {
			break
		}

		chunk := make([]byte, blen)
		if _, err := t.outbuf.Read(chunk); err != nil {
			return err
		}

		if err := t.enqueue(chunk); err != nil {
			return err
		}
	}

	err_t := C.tcp_output(t.client.pcb)
	if err_t != C.ERR_OK {
		return fmt.Errorf("tcp_output: %d", int(err_t))
	}

	return nil
}
Beispiel #3
0
// tcpOutput wraps tcp_output.
func (t *tcpClient) tcpOutput() error {
	t.mu.Lock()
	err_t := C.tcp_output(t.client.pcb)
	t.mu.Unlock()

	if err_t != C.ERR_OK {
		return fmt.Errorf("C.tcp_output: %d", int(err_t))
	}

	return nil
}