bool master_udp::run_alone(const char* addrs, const char* path /* = NULL */, unsigned int count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; __count_limit = count; acl_assert(addrs && *addrs); #ifdef ACL_WINDOWS acl_init(); #endif ACL_EVENT* eventp = acl_event_new_select(1, 0); set_event(eventp); // 设置基类的事件句柄 ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_bind(addr, 0); if (sstream == NULL) { logger_error("bind %s error %s", addr, last_serror()); close_sstreams(); acl_event_free(eventp); acl_argv_free(tokens); return false; } acl_event_enable_read(eventp, sstream, 0, read_callback, sstream); socket_stream* ss = NEW socket_stream(); if (ss->open(sstream) == false) logger_fatal("open stream error!"); sstream->context = ss; sstreams_.push_back(ss); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL, NULL); service_init(NULL, NULL); while (!__stop) acl_event_loop(eventp); service_exit(NULL, NULL); // 必须在调用 acl_event_free 前调用 close_sstreams,因为在关闭 // 网络流对象时依然有对 ACL_EVENT 引擎的使用 close_sstreams(); acl_event_free(eventp); return true; }
bool socket_stream::bind_udp(const char* addr, int rw_timeout /* = 0 */) { if (stream_) acl_vstream_close(stream_); stream_ = acl_vstream_bind(addr, rw_timeout); eof_ = false; opened_ = true; return true; }
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); }