const char* aio_stream::get_peer(bool full /* = false */) const { if (stream_ == NULL) return dummy_; ACL_VSTREAM* vs = acl_aio_vstream(stream_); const char* ptr = ACL_VSTREAM_PEER(vs); if (ptr == NULL || *ptr == 0) { char buf[256]; ACL_SOCKET fd = ACL_VSTREAM_SOCK(vs); if (acl_getpeername(fd, buf, sizeof(buf)) == -1) return dummy_; acl_vstream_set_peer(vs, buf); } ptr = ACL_VSTREAM_PEER(vs); if (full) return ptr; else if (peer_ip_[0] != 0) return peer_ip_; return const_cast<aio_stream*> (this)->get_ip(ptr, const_cast<aio_stream*>(this)->peer_ip_, sizeof(peer_ip_)); }
const char* socket_stream::get_peer_ip() const { if (stream_ == NULL) return dummy_; if (peer_ip_[0] != 0) return peer_ip_; char* ptr = ACL_VSTREAM_PEER(stream_); if (ptr == NULL || *ptr == 0) { char buf[64]; if (acl_getpeername(ACL_VSTREAM_SOCK(stream_), buf, sizeof(buf)) == -1) { return dummy_; } acl_vstream_set_peer(stream_, buf); } return const_cast<socket_stream*> (this)->get_ip( ACL_VSTREAM_PEER(stream_), const_cast<socket_stream*> (this)->peer_ip_, sizeof(peer_ip_)); }
bool socket_stream::set_peer(const char* addr) { if (stream_ == NULL) { logger_error("stream not opened yet!"); return false; } acl_vstream_set_peer(stream_, addr); return true; }
const char* socket_stream::get_peer(bool full /* = false */) const { if (stream_ == NULL) return dummy_; // xxx: acl_vstream 中没有对此地址赋值 char* ptr = ACL_VSTREAM_PEER(stream_); if (ptr == NULL || *ptr == 0) { char buf[64]; if (acl_getpeername(ACL_VSTREAM_SOCK(stream_), buf, sizeof(buf)) == -1) { return dummy_; } acl_vstream_set_peer(stream_, buf); } if (full) return ACL_VSTREAM_PEER(stream_); else return get_peer_ip(); }
ACL_VSTREAM *acl_vstream_accept_ex(ACL_VSTREAM *listen_stream, ACL_VSTREAM *client_stream, char *addr, int size) { const char *myname = "acl_vstream_accept_ex"; ACL_SOCKET connfd = ACL_SOCKET_INVALID; ACL_SOCKET servfd = ACL_VSTREAM_SOCK(listen_stream); char buf[256]; if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_INET)) { #ifdef WIN32 if (!(listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_IOCP)) connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf)); else if (listen_stream->iocp_sock == ACL_SOCKET_INVALID) return NULL; else { int ret; connfd = listen_stream->iocp_sock; listen_stream->iocp_sock = ACL_SOCKET_INVALID; /* iocp 方式下,需调用下面过程以允许调用 * getpeername/getsockname */ ret = setsockopt(connfd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&servfd, sizeof(servfd)); buf[0] = 0; if (ret != SOCKET_ERROR) acl_getpeername(connfd, buf, sizeof(buf)); } #else connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf)); #endif if (connfd != ACL_SOCKET_INVALID && addr != NULL && size > 0) ACL_SAFE_STRNCPY(addr, buf, size); #ifdef ACL_UNIX } else if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_UNIX)) { connfd = acl_unix_accept(servfd); if (acl_getpeername(connfd, buf, sizeof(buf)) < 0) buf[0] = 0; if (addr) ACL_SAFE_STRNCPY(addr, buf, size); #endif } else acl_msg_fatal("%s(%d)->%s: invalid listen stream(%d)", __FILE__, __LINE__, myname, listen_stream->flag); if (connfd == ACL_SOCKET_INVALID) return NULL; if (client_stream != NULL) { acl_vstream_reset(client_stream); ACL_VSTREAM_SET_SOCK(client_stream, connfd); } else { client_stream = acl_vstream_fdopen(connfd, ACL_VSTREAM_FLAG_RW, (int) listen_stream->read_buf_len, listen_stream->rw_timeout, ACL_VSTREAM_TYPE_SOCK); /* 让 client_stream 的 context 成员继承 listen_stream 的 * context 成员变量. */ client_stream->context = listen_stream->context; } if (client_stream == NULL) return NULL; acl_vstream_set_peer(client_stream, buf); return client_stream; }
static void run(const char *local_addr, const char *peer_addr, int count, int dlen, int inter, int need_read, int quit) { double spent; int ret, i; char buf[4096], data[4096]; struct timeval begin, end; ACL_VSTREAM *stream = acl_vstream_bind(local_addr, 2); /* 绑定 UDP 套接口 */ if (stream == NULL) { printf("acl_vstream_bind %s error %s\r\n", local_addr, acl_last_serror()); return; } if (dlen > (int) sizeof(data) - 1) dlen = (int) sizeof(data) - 1; for (i = 0; i < dlen; i++) data[i] = 'X'; data[dlen] = 0; gettimeofday(&begin, NULL); acl_vstream_set_peer(stream, peer_addr); ACL_VSTREAM_SET_RWTIMO(stream, 1); for (i = 0; i < count; i++) { /* 如果服务端的地址是变化的,则应该在写每次前都需要调用 * acl_vstream_set_peer */ ret = acl_vstream_write(stream, data, dlen); if (ret == ACL_VSTREAM_EOF) { printf("acl_vtream_write error %s\r\n", acl_last_serror()); break; } if (need_read) { ret = acl_vstream_read(stream, buf, sizeof(buf) - 1); if (ret == ACL_VSTREAM_EOF) { if (errno == ETIMEDOUT) { printf("timeout read\r\n"); continue; } printf("acl_vstream_read error %s\r\n", acl_last_serror()); break; } else buf[ret] = 0; if (i % inter == 0) printf("result: %s\r\n", buf); } if (i % inter == 0) { snprintf(buf, sizeof(buf), "total: %d, curr: %d", count, i); ACL_METER_TIME(buf); } } gettimeofday(&end, NULL); spent = stamp_sub(&end, &begin); printf("thread: %lu, total: %d, curr: %d, spent: %.2f, speed: %.2f\r\n", (unsigned long) acl_pthread_self(), count, i, spent, (i * 1000) / (spent > 1 ? spent : 1)); printf("thread: %lu, local addr: %s, peer addr: %s\r\n", (unsigned long) acl_pthread_self(), ACL_VSTREAM_LOCAL(stream), ACL_VSTREAM_PEER(stream)); if (quit) acl_vstream_write(stream, "quit", 4); acl_vstream_close(stream); }