int8_t AsyncClient::_close(){ int8_t err = ERR_OK; if(_pcb) { //log_i(""); tcp_arg(_pcb, NULL); tcp_sent(_pcb, NULL); tcp_recv(_pcb, NULL); tcp_err(_pcb, NULL); tcp_poll(_pcb, NULL, 0); if(_in_lwip_thread){ err = tcp_close(_pcb); } else { err = _tcp_close(_pcb); } if(err != ERR_OK) { err = abort(); } _pcb = NULL; if(_discard_cb) _discard_cb(_discard_cb_arg, this); } return err; }
void AsyncServer::begin(){ if(_pcb) return; if(!_start_async_task()){ log_e("failed to start task"); return; } int8_t err; _pcb = tcp_new_ip_type(IPADDR_TYPE_V4); if (!_pcb){ log_e("_pcb == NULL"); return; } ip_addr_t local_addr; local_addr.type = IPADDR_TYPE_V4; local_addr.u_addr.ip4.addr = (uint32_t) _addr; err = _tcp_bind(_pcb, &local_addr, _port); if (err != ERR_OK) { _tcp_close(_pcb); log_e("bind error: %d", err); return; } static uint8_t backlog = 5; _pcb = _tcp_listen_with_backlog(_pcb, backlog); //_pcb = _tcp_listen(_pcb); if (!_pcb) { log_e("listen_pcb == NULL"); return; } tcp_arg(_pcb, (void*) this); tcp_accept(_pcb, &_s_accept); }
static int _tcp_open (mu_stream_t stream) { struct _tcp_instance *tcp = (struct _tcp_instance *)stream; int flgs, ret; socklen_t namelen; struct sockaddr_in peer_addr; int flags; mu_stream_get_flags (stream, &flags); switch (tcp->state) { case TCP_STATE_INIT: if (tcp->fd == -1) { tcp->fd = socket (tcp->remote_addr->addr->sa_family, SOCK_STREAM, 0); if (tcp->fd == -1) return errno; } if (flags & MU_STREAM_NONBLOCK) { flgs = fcntl (tcp->fd, F_GETFL); flgs |= O_NONBLOCK; fcntl (tcp->fd, F_SETFL, flgs); mu_stream_set_flags (stream, MU_STREAM_NONBLOCK); } if (tcp->source_addr) { if (bind (tcp->fd, tcp->source_addr->addr, tcp->source_addr->addrlen) < 0) { int e = errno; close (tcp->fd); tcp->fd = -1; return e; } } tcp->state = TCP_STATE_RESOLVING; case TCP_STATE_RESOLVING: tcp->state = TCP_STATE_RESOLVE; case TCP_STATE_RESOLVE: if (connect (tcp->fd, tcp->remote_addr->addr, tcp->remote_addr->addrlen) == -1) { ret = errno; if (ret == EINPROGRESS || ret == EAGAIN) { tcp->state = TCP_STATE_CONNECTING; ret = EAGAIN; } else _tcp_close (stream); return ret; } tcp->state = TCP_STATE_CONNECTING; case TCP_STATE_CONNECTING: namelen = sizeof (peer_addr); if (getpeername (tcp->fd, (struct sockaddr *) &peer_addr, &namelen) == 0) tcp->state = TCP_STATE_CONNECTED; else { ret = errno; _tcp_close (stream); return ret; } break; } return 0; }