Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
0
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;
}
Example #5
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);
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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);
}
Example #9
0
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();
}
Example #10
0
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;
}
Example #11
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);
	}
Example #12
0
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;
}
Example #14
0
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;
}
Example #15
0
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;
}
Example #16
0
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();
}
Example #17
0
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;
}
Example #18
0
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;
}