Example #1
0
bool net::socket::connect(type type, const socket_address& addr, int timeout)
{
	// Create socket.
	if (!create(addr.ss_family, type)) {
		return false;
	}

	// Connect.
	if ((::connect(_M_fd, reinterpret_cast<const struct sockaddr*>(&addr), addr.size()) < 0) && (errno != EINPROGRESS)) {
		close();
		return false;
	}

	if (timeout != 0) {
		if (!wait_writable(timeout)) {
			close();
			return false;
		}

		int error;
		if ((!get_socket_error(error)) || (error != 0)) {
			close();
			return false;
		}
	}

	return true;
}
Example #2
0
ssize_t net::socket::write(const void* buf, size_t count, int timeout)
{
	if (timeout == 0) {
		ssize_t ret;
		while (((ret = send(_M_fd, buf, count, 0)) < 0) && (errno == EINTR));

		return ret;
	} else {
		const char* b = (const char*) buf;
		size_t written = 0;

		do {
			if (!wait_writable(timeout)) {
				return -1;
			}

			ssize_t ret;
			if ((ret = send(_M_fd, b, count - written, 0)) < 0) {
				if ((errno != EINTR) && (errno != EAGAIN)) {
					return -1;
				}
			} else if (ret > 0) {
				if ((written += ret) == count) {
					return count;
				}

				b += ret;
			}
		} while (true);
	}
}
int TCPSocketConnection::send_all(char *data, int length) {
    if ((_sock_fd < 0) || !_is_connected) {
        return -1;
    }

    int writtenLen = 0;
    TimeInterval timeout(_timeout);
    while (writtenLen < length) {
        if (!_blocking) {
            // Wait for socket to be writeable
            if (wait_writable(timeout) != 0) {
                return writtenLen;
            }
        }

        int ret = _cc3000_module->_socket.send(_sock_fd, data + writtenLen, length - writtenLen, 0);
        if (ret > 0) {
            writtenLen += ret;
            continue;
        } else if (ret == 0) {
            _is_connected = false;
            return writtenLen;
        } else {
            return -1; //Connnection error
        }
    }

    return writtenLen;
}
Example #4
0
ssize_t net::socket::writev(const struct iovec* iov, unsigned iovcnt, int timeout)
{
	if (timeout == 0) {
		ssize_t ret;
		while (((ret = ::writev(_M_fd, iov, iovcnt)) < 0) && (errno == EINTR));

		return ret;
	} else {
		if (iovcnt > IOV_MAX) {
			errno = EINVAL;
			return -1;
		}

		struct iovec vec[IOV_MAX];
		size_t total = 0;

		for (unsigned i = 0; i < iovcnt; i++) {
			vec[i].iov_base = iov[i].iov_base;
			vec[i].iov_len = iov[i].iov_len;

			total += vec[i].iov_len;
		}

		struct iovec* v = vec;
		size_t written = 0;

		do {
			if (!wait_writable(timeout)) {
				return -1;
			}

			ssize_t ret;
			if ((ret = ::writev(_M_fd, v, iovcnt)) < 0) {
				if ((errno != EINTR) && (errno != EAGAIN)) {
					return -1;
				}
			} else if (ret > 0) {
				if ((written += ret) == total) {
					return total;
				}

				while ((size_t) ret >= v->iov_len) {
					ret -= v->iov_len;

					v++;
					iovcnt--;
				}

				if (ret > 0) {
					v->iov_base = (char*) v->iov_base + ret;
					v->iov_len -= ret;
				}
			}
		} while (true);
	}
}
int TCPSocketConnection::send(char* data, int length) {
    if ((_sock_fd < 0) || !_is_connected) {
        return -1;
    }

    if (!_blocking) {
        TimeInterval timeout(_timeout);
        if (wait_writable(timeout) != 0) {
            return -1;
        }
    }

    int n = _cc3000_module->_socket.send(_sock_fd, data, length, 0);
    _is_connected = (n != 0);

    return n;
}
Example #6
0
static int send_all(int sockfd, char *buf, size_t length)
{
    int bytes_sent = 0;
    struct timeval timeout = {HTTP_DEFAULT_TIMEOUT, 0};
    while (bytes_sent < (int)length) {
        int ret = wait_writable(sockfd, timeout);
        if (ret != 0)
            return -1;

        ret = send(sockfd, buf + bytes_sent, length - bytes_sent, 0);
        if (ret > 0) {
            bytes_sent += ret;
            continue;
        } else if (ret == 0) {
            return bytes_sent;
        } else {
            return -1;
        }
    }
    return bytes_sent;
}
Example #7
0
int make_dns_query(char *buf, int query_len, time_t *ttl, int *Anum)
{
    struct sockaddr_in addr;
    int sockfd = -1;
    struct timeval timeout = { RETRANS_INTERVAL, 0 };
    int i, ret = -1;
    int addrlen, send_len, result_len;
    int try_num = 0;
    dns_head_type *dns_head;
#ifdef WIN32
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif

    addr.sin_family = AF_INET;
    //addr.sin_addr.s_addr = inet_addr(PUBLIC_DNS_DEFAULT_SERVER);
    inet_pton(AF_INET, PUBLIC_DNS_DEFAULT_SERVER, &(addr.sin_addr.s_addr));
    addr.sin_port = htons((uint16_t)PUBLIC_DNS_DEFAULT_PORT);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == sockfd) {
        fprintf(stderr, "socket error\n");
        goto clear;
    }

    ret = wait_writable(sockfd, timeout);
    if (ret != 0) {
        fprintf(stderr, "wait writable timeout\n");
        goto clear;
    }
    while (try_num++ <= RETRANS_TRY_NUM) {
        send_len = sendto(sockfd, buf, query_len, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr));
        if (send_len != query_len) {
            fprintf(stderr, "sendto dns query failed\n");
            ret = -1;
            goto clear;
        }
        ret = wait_readable(sockfd, timeout);
        if (ret == 0) {
            break;
        }
    }
    if (try_num > RETRANS_TRY_NUM) {
        fprintf(stderr, "dns query failed over try num\n");
        ret = -1;
        goto clear;
    }

    addrlen = sizeof(struct sockaddr);
    result_len = recvfrom(sockfd, buf, DNS_DEFAULT_DATA_SIZE, 0/*MSG_WAITALL*/,
        (struct sockaddr *)&addr, (socklen_t*)&addrlen);
    if (result_len <= 0) {
        fprintf(stderr, "receve dns response failed\n");
        ret = -1;
        goto clear;
    }

    //只支持A记录
    dns_head = (dns_head_type *)buf;
    int off = 0;
    int num = DNS_GET16(dns_head->numA);
    for (i = 0; i < num; i++) {
        char *result_set = buf + query_len + off;
        response *rp = (response *)(result_set + 2); //2 bytes' offsets
        uint16_t type = DNS_GET16(rp->type);
        *ttl = DNS_GET32(rp->ttl);
        //解析A记录
        if (TYPE_A == type) {
            memcpy(buf + (*Anum) * 4, (char *)(rp + 1), 4);
            (*Anum)++;
            off += (2 + sizeof(response) + 4);
        }
        else if (TYPE_CNAME == type) {
            //如果是CNAME记录则直接查找下一条记录
            off += (2 + sizeof(response) + DNS_GET16(rp->length));
        }
        else {
            //其他类型不支持
            goto clear;
        }
    }

    ret = 0;

clear:
    if (sockfd != -1) {
#ifdef WIN32
        closesocket(sockfd);
        WSACleanup();
#else
        close(sockfd);
#endif
    }

    return ret;
}