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; }
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; }
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; }
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; }
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; }