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; }
static void* stream_blocking_thread(void* arg) { int iloop; socket_t* sock = (socket_t*)arg; char buffer_out[317] = {0}; char buffer_in[317] = {0}; stream_t* stream = socket_stream(sock); for (iloop = 0; !thread_try_wait(0) && iloop < 512; ++iloop) { log_infof(HASH_NETWORK, STRING_CONST("UDP write pass %d"), iloop); EXPECT_SIZEEQ(stream_write(stream, buffer_out, 127), 127); EXPECT_SIZEEQ(stream_write(stream, buffer_out + 127, 180), 180); stream_flush(stream); EXPECT_SIZEEQ(stream_write(stream, buffer_out + 307, 10), 10); stream_flush(stream); log_infof(HASH_NETWORK, STRING_CONST("UDP read pass %d"), iloop); EXPECT_SIZEEQ(stream_read(stream, buffer_in, 235), 235); EXPECT_SIZEEQ(stream_read(stream, buffer_in + 235, 82), 82); thread_yield(); } log_debugf(HASH_NETWORK, STRING_CONST("IO complete on socket 0x%llx"), sock); stream_deallocate(stream); return 0; }
bool http_client::open(const char* addr, int conn_timeout /* = 60 */, int rw_timeout /* = 60 */, bool unzip /* = true */) { is_request_ = true; if (stream_ && !stream_fixed_) { delete stream_; stream_ = NULL; disconnected_ = true; } socket_stream* stream = NEW socket_stream(); rw_timeout_ = rw_timeout; unzip_ = unzip; if (stream->open(addr, conn_timeout, rw_timeout) == false) { delete stream; disconnected_ = true; return false; } disconnected_ = false; stream_ = stream; return true; }
int master_threads::service_on_accept(ACL_VSTREAM* client) { // client->context 不应被占用 if (client->context != NULL) logger_fatal("client->context not null!"); socket_stream* stream = NEW socket_stream(); if (stream->open(client) == false) { logger_error("open stream error(%s)", acl_last_serror()); delete stream; return -1; } // 设置 client->context 为流对象 client->context = stream; acl_assert(__mt != NULL); if (__mt->thread_on_accept(stream) == false) { client->context = NULL; // 解释与连接流的绑定关系,这样可以防止在删除流对象时 // 真正关闭了连接流,因为该流连接需要在本函数返回后由 // 框架自动关闭 (void) stream->unbind(); // 删除流对象 delete stream; // 让框架关闭连接流 return -1; } return 0; }
bool ipc_client::open(const char* addr, int timeout) { acl_assert(sync_stream_ == NULL && async_stream_ == NULL); sync_stream_ = NEW socket_stream(); if (sync_stream_->open(addr, timeout, 0) == false) { delete sync_stream_; sync_stream_ = NULL; return (false); } sync_stream_inner_ = sync_stream_; return (true); }
void master_proc::service_main(ACL_VSTREAM *stream, char*, char**) { socket_stream* client = NEW socket_stream(); if (client->open(stream) == false) logger_fatal("open stream error!"); acl_assert(__mp != NULL); #ifndef ACL_WINDOWS if (__mp->daemon_mode_) acl_watchdog_pat(); // 必须通知 acl_master 框架一下 #endif __mp->on_accept(client); client->unbind(); delete client; }
bool memcache::open() { if (opened_) return true; conn_ = NEW socket_stream(); if (conn_->open(addr_, conn_timeout_, rw_timeout_) == false) { logger_error("connect %s error(%s)", addr_, last_serror()); delete conn_; conn_ = NULL; opened_ = false; ebuf_.format("connect server(%s) error(%s)", addr_, acl_last_serror()); return false; } opened_ = true; return true; }
void master_udp::service_main(ACL_VSTREAM *stream, char*, char**) { acl_assert(__mu != NULL); socket_stream* ss = (socket_stream*) stream->context; if (ss == NULL) { // 当本函数第一次被调用时,需要打开 socket_stream 流 ss = NEW socket_stream(); if (ss->open(stream) == false) logger_fatal("open stream error!"); stream->context = ss; acl_vstream_add_close_handle(stream, on_close, ss); } #ifndef ACL_WINDOWS if (__mu->daemon_mode_) acl_watchdog_pat(); // 必须通知 acl_master 框架一下 #endif __mu->on_read(ss); }
void master_udp::service_init(char*, char**) { acl_assert(__mu != NULL); #ifndef ACL_WINDOWS if (__mu->daemon_mode_) { ACL_VSTREAM** streams = acl_udp_server_streams(); for (int i = 0; streams[i] != NULL; i++) { socket_stream* ss = NEW socket_stream(); if (ss->open(streams[i]) == false) logger_fatal("open stream error!"); __mu->sstreams_.push_back(ss); } } #endif __mu->proc_inited_ = true; __mu->proc_on_init(); }
int master_threads2::service_on_accept(ACL_VSTREAM* client) { // client->context 不应被占用 if (client->context != NULL) logger_fatal("client->context not null!"); socket_stream* stream = NEW socket_stream(); // 设置 client->context 为流对象,该流对象将统一在 // service_on_close 中被释放 client->context = stream; if (stream->open(client) == false) { logger_error("open stream error(%s)", acl_last_serror()); // 返回 -1 由上层框架调用 service_on_close 过程,在里面 // 释放 stream 对象 return -1; } acl_assert(__mt != NULL); // 如果子类的 thread_on_accept 方法返回 false,则直接返回给上层 // 框架 -1,由上层框架再调用 service_on_close 过程,从而在该过程 // 中将 stream 对象释放 if (__mt->thread_on_accept(stream) == false) return -1; // 如果子类的 thread_on_handshake 方法返回 false,则直接返回给上层 // 框架 -1,由上层框架再调用 service_on_close 过程,从而在该过程 // 中将 stream 对象释放 if (__mt->thread_on_handshake(stream) == false) return -1; // 返回 0 表示可以继续处理该客户端连接,从而由上层框架将其置入 // 读监控集合中 return 0; }
bool mem_cache::open() { if (m_opened) return (true); m_conn = NEW socket_stream(); char addr[64]; snprintf(addr, sizeof(addr), "%s:%d", m_ip, m_port); if (m_conn->open(addr, m_conn_timeout, m_rw_timeout) == false) { logger_error("connect %s error(%s)", addr, acl::last_serror()); delete m_conn; m_conn = NULL; m_opened = false; m_ebuf.format("connect server(%s) error(%s)", addr, acl_last_serror()); return (false); } m_opened = true; return (true); }
bool HttpServlet::start() { socket_stream* in; socket_stream* out; bool cgi_mode; bool first = first_; if (first_) first_ = false; if (stream_ == NULL) { // 数据流为空,则当 CGI 模式处理,将标准输入输出 // 作为数据流 in = NEW socket_stream(); in->open(ACL_VSTREAM_IN); out = NEW socket_stream(); out->open(ACL_VSTREAM_OUT); cgi_mode = true; } else { in = out = stream_; cgi_mode = false; } // 在 HTTP 长连接重复请求情况下,以防万一,需要首先删除请求/响应对象 delete req_; delete res_; res_ = NEW HttpServletResponse(*out); req_ = NEW HttpServletRequest(*res_, *session_, *in, local_charset_, parse_body_enable_, parse_body_limit_); // 设置 HttpServletRequest 对象 res_->setHttpServletRequest(req_); if (rw_timeout_ >= 0) req_->setRwTimeout(rw_timeout_); res_->setCgiMode(cgi_mode); string method_s(32); http_method_t method = req_->getMethod(&method_s); // 根据请求的值自动设定是否需要保持长连接 if (!cgi_mode) res_->setKeepAlive(req_->isKeepAlive()); bool ret; switch (method) { case HTTP_METHOD_GET: if (upgradeWebsocket(*req_, *res_)) { if (res_->sendHeader() == false) { logger_error("sendHeader error!"); return false; } ret = doWebsocket(*req_, *res_); } else ret = doGet(*req_, *res_); break; case HTTP_METHOD_POST: ret = doPost(*req_, *res_); break; case HTTP_METHOD_PUT: ret = doPut(*req_, *res_); break; case HTTP_METHOD_CONNECT: ret = doConnect(*req_, *res_); break; case HTTP_METHOD_PURGE: ret = doPurge(*req_, *res_); break; case HTTP_METHOD_DELETE: ret = doDelete(*req_, *res_); break; case HTTP_METHOD_HEAD: ret = doHead(*req_, *res_); break; case HTTP_METHOD_OPTION: ret = doOptions(*req_, *res_); break; case HTTP_METHOD_PROPFIND: ret = doPropfind(*req_, *res_); break; case HTTP_METHOD_OTHER: ret = doOther(*req_, *res_, method_s.c_str()); break; default: ret = false; // 有可能是IO失败或未知方法 if (req_->getLastError() == HTTP_REQ_ERR_METHOD) doUnknown(*req_, *res_); else if (first) doError(*req_, *res_); break; } if (in != out) { // 如果是标准输入输出流,则需要先将数据流与标准输入输出解绑, // 然后才能释放数据流对象,数据流内部会自动判断流句柄合法性 // 这样可以保证与客户端保持长连接 in->unbind(); out->unbind(); delete in; delete out; } return ret; }
void main(void) { int Time_Gap=0,Clock_Time,Clock_Time_last,i; int TimeS = 0; char key=0; image area; image cur_img,bkg_img,ept_img; image cur_middlewin_img,bkg_middlewin_img,ert_smallwin_img; int x_lable = 0,y_lable = 0; //int x_lable_ = 0,y_lable = 0; int X0,Y0; int x_ofs,y_ofs; int wind_flag = 0; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ unsigned char *linebuffer; int sendbuf[5]; sockaddr_in laddr, raddr; unsigned sock, listensock; unsigned error; uint_16 rlen; int result; int ms1,kms; char receivedata[RECEIVE_BYTES]; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ init_licence("T2237AE5748"); // ==================================================================================== // ==================================================================================== mem_init(); // ----------------------------------------- //开始程序前,拍下空的背景图片,并调节亮度 Brightness_Adjust(); //==================================================================================== OvlClearAll; print("Press any key to start\n"); print("Press 'q' to quit\n"); print("Press 'c' to clear screen\n"); getchar(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* server services port */ laddr.sin_family = AF_INET; laddr.sin_port = SERVER_PORT; /* server listen at port SERVER_PORT (2002) */ laddr.sin_addr.s_addr = INADDR_ANY; /* every IP addr can connect to the camera */ /* use TCP/IP protocoll and search for a free port */ sock = socket_stream(); if (sock == VCRT_HANDLE_ERROR) { print("\nCreate stream socket failed"); return; } /* connection between free port and selected SERVER_PORT. Now SERVER_PORT is free again for new connections. */ error = bind(sock, &laddr, sizeof(laddr)); if (error != VCRT_OK) { print("\nStream bind failed - 0x%x", error); return; } /* activate sock for TCP/IP connections */ error = listen(sock, 0); if (error != VCRT_OK) { print("\nListen failed - 0x%x", error); return; } listensock = sock; print("\n\nFast Ethernet port %d\n",laddr.sin_port); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ while(1) { /* Are there connections at any port? The number 0 means: Wait until connection */ sock = VCRT_selectall(0); /* Is there one who wants to connect to port SERVER_PORT */ if (sock == listensock) { /* Connection requested; accept it */ rlen = sizeof(raddr); /* accept connection */ print("\nwait for accept"); sock = accept(listensock, &raddr, &rlen); if (sock == VCRT_HANDLE_ERROR) { print("\nAccept failed, error 0x%x",VCRT_geterror(listensock)); continue; } else { print("\naccept ready"); } print("\nConnection from %d.%d.%d.%d, port %d", (raddr.sin_addr.s_addr >> 24) & 0xFF, (raddr.sin_addr.s_addr >> 16) & 0xFF, (raddr.sin_addr.s_addr >> 8) & 0xFF, raddr.sin_addr.s_addr & 0xFF, raddr.sin_port); do { if (kbhit()) { key = rs232rcv(); if(key == 'c')OvlClearAll; } sendbuf[0] = 0; sendbuf[1] = 0; sendbuf[2] = 0; sendbuf[3] = 0; sendbuf[4] = 0; recv(sock, (char *)receivedata, RECEIVE_BYTES, 0); /* measure time */ /* take next Screen (mode=0) */ ScreenBuffer(NextScreen,&area); // ms1=Clock_Time; Clock_Time = getvar(MSEC); Time_Gap = Clock_Time - Clock_Time_last; if(Clock_Time<0)Clock_Time += 1000; Clock_Time_last = Clock_Time; /* if(Clock_Time<ms1) { kms=ms1/1000; if((Clock_Time+kms*1000)>ms1) Clock_Time+=kms*1000; else Clock_Time+=(kms+1)*1000; } */ // print("Clock_Time = %d\n",Clock_Time); //wind_flag = 0; ImageAssign(&cur_img, (long)Screen[Cur_index] , BigWinColumns, BigWinRows, ScrGetPitch); ImageAssign(&bkg_img, (long)Screen[BackGrand_index] , BigWinColumns, BigWinRows, ScrGetPitch); ImageAssign(&ept_img, (long)EptBckPage , BigWinColumns, BigWinRows, ScrGetPitch); #ifdef _USE_SMALL_WINDOW_ if(wind_flag == 1 )//上次找到了乒乓球 { //预测新的窗口位置 x_ofs = x_lable_his[his_near_pos] - x_lable_his[his_far_pos]; if(x_ofs > dx_win_max)x_ofs = dx_win_max; else if( x_ofs < -dx_win_max)x_ofs = - dx_win_max; y_ofs = y_lable_his[his_near_pos] - y_lable_his[his_far_pos]; if(y_ofs > dx_win_max)y_ofs = dx_win_max; else if( y_ofs < -dx_win_max)y_ofs = - dx_win_max; X0 = x_lable + x_ofs - MiddleWinColumns/2; Y0 = y_lable + y_ofs - MiddleWinRows/2; if(X0<0)X0=0; else if(X0 + MiddleWinColumns >= BigWinColumns)X0=BigWinColumns-1-MiddleWinColumns; if(Y0<0)Y0=0; else if(Y0 + MiddleWinRows >= BigWinRows)Y0 = BigWinRows-1-MiddleWinRows; //=============================================================== ImageAssign(&cur_middlewin_img, (cur_img.st + X0 + Y0 * ScrGetPitch), MiddleWinColumns, MiddleWinRows, ScrGetPitch); ImageAssign(&bkg_middlewin_img, (bkg_img.st + X0 + Y0 * ScrGetPitch), MiddleWinColumns, MiddleWinRows, ScrGetPitch); ImageAssign(&ert_smallwin_img , (ept_img.st + X0 + Y0 * ScrGetPitch), MiddleWinColumns, MiddleWinRows, ScrGetPitch); if( 1 == Find_pp_pos(cur_middlewin_img,bkg_middlewin_img,ert_smallwin_img,&x_lable,&y_lable,DCUR_TH) ) { wind_flag = 1; x_lable += X0; y_lable += Y0; upload_lable_his(x_lable,y_lable); mark(x_lable,y_lable,"*"); sendbuf[0] = 1; sendbuf[1] = x_lable*10; sendbuf[2] = y_lable*10; sendbuf[3] = Clock_Time; sendbuf[4] = TimeS; } else wind_flag = 0; /* else { x_lable = x_lable_his[his_near_pos]; y_lable = y_lable_his[his_near_pos]; wind_flag = GSP(cur_img,&x_lable,&y_lable); if(wind_flag) { mark(x_lable,y_lable,"*"); upload_lable_his(x_lable,y_lable); } sendbuf[0] = 1; sendbuf[1] = x_lable; sendbuf[2] = y_lable; sendbuf[3] = 2; sendbuf[4] = 3; // else // mark(x_lable,y_lable,"O"); }*/ /* calculation time */ } if( wind_flag == 0 )//上次没找到乒乓球,或者这次在小窗口和中等窗口都没找到乒乓球,则在大窗口找 #endif//_USE_SMALL_WINDOW_ { //------------------------------------------------------------------- wind_flag = Find_pp_pos(cur_img,bkg_img,ept_img,&x_lable,&y_lable,dimg_threshold); //这样赋值以确保x_ofs和y_ofs为0 x_lable_his[his_near_pos] = x_lable; y_lable_his[his_near_pos] = y_lable; x_lable_his[his_far_pos ] = x_lable; y_lable_his[his_far_pos ] = y_lable; // mark(x_lable,y_lable,"s"); } sendbuf[3] = Time_Gap; linebuffer = (unsigned char*)sendbuf; result=send(sock, (char *)linebuffer, 20, 0); if(result==VCRT_ERROR) { print("\nSend VCRT_ERROR=%lx",VCRT_geterror(sock)); } }while(key != 'q'); shutdown(sock, FLAG_CLOSE_TX); print("\nshutdown\n"); } print("\nidle\n"); shutdown(listensock, FLAG_CLOSE_TX); break; }
bool HttpServlet::doRun(session& session, socket_stream* stream /* = NULL */, bool body_parse /* = true */, int body_limit /* = 102400 */) { socket_stream* in; socket_stream* out; bool cgi_mode; if (stream == NULL) { // 数据流为空,则当 CGI 模式处理,将标准输入输出 // 作为数据流 stream = NEW socket_stream(); (void) stream->open(ACL_VSTREAM_IN); in = stream; stream = NEW socket_stream(); (void) stream->open(ACL_VSTREAM_OUT); out = stream; cgi_mode = true; } else { in = out = stream; cgi_mode = false; } // req/res 采用栈变量,减少内存分配次数 HttpServletResponse res(*out); HttpServletRequest req(res, session, *in, local_charset_, body_parse, body_limit); if (rw_timeout_ >= 0) req.setRwTimeout(rw_timeout_); res.setCgiMode(cgi_mode); bool ret; http_method_t method = req.getMethod(); if (method == HTTP_METHOD_GET) ret = doGet(req, res); else if (method == HTTP_METHOD_POST) ret = doPost(req, res); else if (method == HTTP_METHOD_PUT) ret = doPut(req, res); else if (method == HTTP_METHOD_CONNECT) ret = doConnect(req, res); else if (method == HTTP_METHOD_PURGE) ret = doPurge(req, res); else { ret = false; // 有可能是IO失败或未知方法 http_request_error_t n = req.getLastError(); if (n == HTTP_REQ_ERR_METHOD) doUnknown(req, res); else doError(req, res); } if (in != out) { // 如果是标准输入输出流,则需要先将数据流与标准输入输出解绑, // 然后才能释放数据流对象,数据流内部会自动判断流句柄合法性 // 这样可以保证与客户端保持长连接 in->unbind(); out->unbind(); delete in; delete out; } return ret; }
bool HttpServlet::doRun(session& session, socket_stream* stream /* = NULL */) { socket_stream* in; socket_stream* out; bool cgi_mode; if (stream == NULL) { // 数据流为空,则当 CGI 模式处理,将标准输入输出 // 作为数据流 stream = NEW socket_stream(); (void) stream->open(ACL_VSTREAM_IN); in = stream; stream = NEW socket_stream(); (void) stream->open(ACL_VSTREAM_OUT); out = stream; cgi_mode = true; } else { in = out = stream; cgi_mode = false; } // req/res 采用栈变量,减少内存分配次数 HttpServletResponse res(*out); HttpServletRequest req(res, session, *in, local_charset_, parse_body_enable_, parse_body_limit_); if (rw_timeout_ >= 0) req.setRwTimeout(rw_timeout_); res.setCgiMode(cgi_mode); bool ret; http_method_t method = req.getMethod(); switch (method) { case HTTP_METHOD_GET: ret = doGet(req, res); break; case HTTP_METHOD_POST: ret = doPost(req, res); break; case HTTP_METHOD_PUT: ret = doPut(req, res); break; case HTTP_METHOD_CONNECT: ret = doConnect(req, res); break; case HTTP_METHOD_PURGE: ret = doPurge(req, res); break; case HTTP_METHOD_DELETE: ret = doDelete(req, res); break; case HTTP_METHOD_HEAD: ret = doHead(req, res); break; case HTTP_METHOD_OPTION: ret = doOption(req, res); break; default: ret = false; // 有可能是IO失败或未知方法 if (req.getLastError() == HTTP_REQ_ERR_METHOD) doUnknown(req, res); else doError(req, res); break; } if (in != out) { // 如果是标准输入输出流,则需要先将数据流与标准输入输出解绑, // 然后才能释放数据流对象,数据流内部会自动判断流句柄合法性 // 这样可以保证与客户端保持长连接 in->unbind(); out->unbind(); delete in; delete out; } return ret; }
bool HttpServlet::doRun(dbuf_pool* dbuf) { socket_stream* in; socket_stream* out; bool cgi_mode; bool first = first_; if (first_) first_ = false; if (stream_ == NULL) { // 数据流为空,则当 CGI 模式处理,将标准输入输出 // 作为数据流 in = NEW socket_stream(); in->open(ACL_VSTREAM_IN); out = NEW socket_stream(); out->open(ACL_VSTREAM_OUT); cgi_mode = true; } else { in = out = stream_; cgi_mode = false; } // req/res 采用栈变量,减少内存分配次数 HttpServletResponse res(*out, dbuf); HttpServletRequest req(res, *session_, *in, local_charset_, parse_body_enable_, parse_body_limit_, dbuf); // 设置 HttpServletRequest 对象 res.setHttpServletRequest(&req); if (rw_timeout_ >= 0) req.setRwTimeout(rw_timeout_); res.setCgiMode(cgi_mode); string method_s(32); http_method_t method = req.getMethod(&method_s); // 根据请求的值自动设定是否需要保持长连接 if (!cgi_mode) res.setKeepAlive(req.isKeepAlive()); bool ret; switch (method) { case HTTP_METHOD_GET: ret = doGet(req, res); break; case HTTP_METHOD_POST: ret = doPost(req, res); break; case HTTP_METHOD_PUT: ret = doPut(req, res); break; case HTTP_METHOD_CONNECT: ret = doConnect(req, res); break; case HTTP_METHOD_PURGE: ret = doPurge(req, res); break; case HTTP_METHOD_DELETE: ret = doDelete(req, res); break; case HTTP_METHOD_HEAD: ret = doHead(req, res); break; case HTTP_METHOD_OPTION: ret = doOptions(req, res); break; case HTTP_METHOD_PROPFIND: ret = doPropfind(req, res); break; case HTTP_METHOD_OTHER: ret = doOther(req, res, method_s.c_str()); break; default: ret = false; // 有可能是IO失败或未知方法 if (req.getLastError() == HTTP_REQ_ERR_METHOD) doUnknown(req, res); else if (first) doError(req, res); break; } if (in != out) { // 如果是标准输入输出流,则需要先将数据流与标准输入输出解绑, // 然后才能释放数据流对象,数据流内部会自动判断流句柄合法性 // 这样可以保证与客户端保持长连接 in->unbind(); out->unbind(); delete in; delete out; } // 返回给上层调用者:true 表示继续保持长连接,否则表示需断开连接 return ret && req.isKeepAlive() && res.getHttpHeader().get_keep_alive(); }
bool CTCPSocket::Open(const unsigned char *ip, int port) { Close(); #ifdef WIN32 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { m_socket = -1; return false; } m_socket = (int)sock; struct sockaddr_in serv_addr; memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4); serv_addr.sin_port = htons(port); if (connect(sock, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { Close(); return false; } // set non blocking (after connect) u_long v = 1; if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) { printf("setting non-blocking option failed\n"); Close(); return false; } // set no delay for sending int v2 = 1; if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v2, sizeof(v2)) == -1) { printf("socket couldn't be set to no delay mode\n"); } m_bListening = false; #elif defined(__TI_COMPILER_VERSION__) uint_32 error; m_socket = socket_stream(); if (m_socket == VCRT_SOCKET_ERROR) { printf("Error in Open(): socket_stream() failed\n"); m_socket = -1; return false; } sockaddr_in serv_addr; memset( &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; //never cast ip to an int pointer! this would imply 4byte alignment. memcpy(&(serv_addr.sin_addr.s_addr), ip, 4); // vcrt expects inverse order of ip chars // than provided by RemoteApplicationHandler.cpp serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr); serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order //printf("DEBUG: chars %d,%d,%d,%d, serv_addr.sin_addr.s_addr: 0x%x\n", ip[0], ip[1], ip[2], ip[3], serv_addr.sin_addr.s_addr); error = connect(m_socket, &serv_addr, sizeof(serv_addr)); if (error != VCRT_OK) { printf("Error in Open(): connect failed, error code 0x%x\n", error); Close(); return false; } // set non blocking (after connect) // there is no socket-global (non-)blocking flag on VCRT // - accept() is always blocking and therefore guarded by VCRT_selectset(). // - recv() behavior is set during Recv() depending on bWait flag // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms uint_32 opt_value; opt_value = TRUE; error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value)); if (error != VCRT_OK) { printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error); Close(); return false; } // set no delay for sending // OPT_NO_NAGLE_ALGORITHM is the VCRT equivalent to TCP_NODELAY opt_value = TRUE; error = setsockopt(m_socket, SOL_TCP, OPT_NO_NAGLE_ALGORITHM, &opt_value, sizeof(opt_value)); if (error != VCRT_OK) { printf("Error, setsockopt(OPT_NO_NAGLE_ALGORITHM) failed with error code 0x%x\n", error); Close(); return false; } m_bListening = false; #else m_socket = socket(AF_INET, SOCK_STREAM, 0); if (m_socket < 0) { m_socket = -1; return false; } struct sockaddr_in serv_addr; bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4); serv_addr.sin_port = htons(port); if (connect(m_socket, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { Close(); return false; } // set non blocking (after connect) if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1) { Close(); return false; } // set no delay for sending int v = 1; if (setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)) == -1) { Close(); return false; } m_bListening = false; #endif return true; }
bool CTCPSocket::Listen(const unsigned char *ip, int port) { Close(); #ifdef WIN32 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { m_socket = -1; return false; } m_socket = (int)sock; // set linger on - helps in closing socket immidiately linger li; li.l_onoff = true; li.l_linger = 0; if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*)&li, sizeof(li)) == -1) { printf("setting linger option failed\n"); Close(); return false; } // set non blocking u_long v = 1; if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) { printf("setting non-blocking option failed\n"); Close(); return false; } struct sockaddr_in serv_addr; memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (ip != NULL) { memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4); } else { serv_addr.sin_addr.s_addr = INADDR_ANY; } serv_addr.sin_port = htons(port); if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { Close(); return false; } listen(sock, 5); m_bListening = true; #elif defined(__TI_COMPILER_VERSION__) uint_32 error; m_socket = socket_stream(); if (m_socket == VCRT_SOCKET_ERROR) { m_socket = -1; return false; } //set linger on - helps in closing socket immidiately // SO_LINGER socket option is not available on VCRT. // But in Close() the shutdown flag FLAG_ABORT_CONNECTION enforces hard closing of the socket // as would SO_LINGER with zero timeout on other platforms. //set non blocking // there is no socket-global (non-)blocking flag on VCRT // - accept() is always blocking and therefore guarded by VCRT_selectset(). // - recv() behavior is set during Recv() depending on bWait flag // - send(): don't wait for data to be transmitted, return after buffering. this resembles behavior of Send() on other platforms uint_32 opt_value = TRUE; error = setsockopt(m_socket, SOL_TCP, OPT_SEND_NOWAIT, &opt_value, sizeof(opt_value)); if (error != VCRT_OK) { printf("Error, setsockopt(OPT_SEND_NOWAIT) failed with error code 0x%x\n", error); Close(); return false; } sockaddr_in serv_addr; memset( &serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (ip != NULL) { //never cast ip to an int pointer! this would imply 4byte alignment. memcpy((char *)&serv_addr.sin_addr.s_addr, ip, 4); // vcrt expects inverse order of ip chars // than provided by RemoteApplicationHandler.cpp serv_addr.sin_addr.s_addr = revert_byte_order(serv_addr.sin_addr.s_addr); } else { serv_addr.sin_addr.s_addr = INADDR_ANY; } serv_addr.sin_port = port; //htons(port); VCRT does not want the port in network byte order error = bind(m_socket, &serv_addr, sizeof(serv_addr)); if (error!=VCRT_OK) { printf("\nsocket bind failed, error code: 0x%x\n", error); Close(); return false; } error = listen(m_socket, 5); if (error!=VCRT_OK) { printf("\nsocket listen failed, error code: 0x%x\n", error); Close(); return false; } m_bListening = true; #else m_socket = socket(AF_INET, SOCK_STREAM, 0); if (m_socket < 0) { m_socket = -1; return false; } // set linger on - helps in closing socket immidiately linger li; li.l_onoff = true; li.l_linger = 0; if(setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &li, sizeof(li)) == -1) { printf("setting linger option failed\n"); Close(); return false; } // set non blocking if (fcntl(m_socket, F_SETFL, O_NONBLOCK) == -1) { printf("setting non-blocking option failed\n"); Close(); return false; } struct sockaddr_in serv_addr; bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (ip != NULL) { bcopy(ip, (char *)&serv_addr.sin_addr.s_addr, 4); } else { serv_addr.sin_addr.s_addr = INADDR_ANY; } serv_addr.sin_port = htons(port); if (bind(m_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { Close(); return false; } listen(m_socket, 5); m_bListening = true; #endif return true; }