Ejemplo n.º 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.")
}
Ejemplo n.º 2
0
// tcpWrite wraps tcp_write.
func (t *tcpClient) tcpWrite(chunk []byte) error {
	clen := len(chunk)
	cchunk := C.CString(string(chunk))
	defer C.free(unsafe.Pointer(cchunk))

	t.mu.Lock()
	err_t := C.tcp_write(t.client.pcb, unsafe.Pointer(cchunk), C.uint16_t(clen), C.TCP_WRITE_FLAG_COPY)
	t.mu.Unlock()

	switch err_t {
	case C.ERR_OK:
		t.accWritten(uint64(clen))
		return nil
	case C.ERR_MEM:
		return errBufferIsFull
	}

	return fmt.Errorf("C.tcp_write: %d", int(err_t))
}