none
windows 线程池. 发送无效的参数给服务或功能 RRS feed

  • 问题

  • 我使用的是windows server R2 64位,VS 2013 desktop版本
    创建了一个服务器,在listen接收到socket之后,使用CreateThreadpoolIo创建一个tpio与这个socket绑定,然后用StartThreadpoolIo 和WSARecv()来接收数据,同时我还想实现接收超时的设置工作,我又使用了CreateThreadpoolTimer()并和这个socket关联着,在成功调用WSARecv()之后,我立即调用SetThreadpoolTimer()来启动一个定时器,用来监控这个socket在设定的时间之内有没有收到数据,现在出现崩溃现象

    必然崩溃的过程描述:在超时之后触发时间处理函数,并且这个函数中调用了CancelThreadpoolIo()来停止调用tpio的回调处理,现在还在这个超时处理函数中,打上断点,如果此时终端发送出数据,服务端继续运行并调用StartThreadpoolIo() & WRARecv() 再次启动接收数据,在调用StartThreadpoolIo()时就会出现崩溃,弹出的窗口如下

    我在MSDN上面找了相关的函数说明,但是都没有找到这个问题的原因,能帮我分析一下是什么问题导致的么

    现测试了一下, 如果在  超时处理过程中  终端没有发数据过来的话,程序就没有这个崩溃的现象。为什么?


    emyueguang

    2014年11月12日 9:09

全部回复

  • 你好,

    这样的描述有些抽象,能否给出相关代码?还有具体崩溃时报的错误?

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年11月13日 6:46
  • // tp timer callback
    VOID NTAPI _tp_timeout_cb(
    	_Inout_     PTP_CALLBACK_INSTANCE Instance,
    	_Inout_opt_ PVOID                 Context,
    	_Inout_     PTP_TIMER             Timer)
    {
    	netfd	*fd = (netfd*)Context;
    
    	logc(CT_GREEN, 0, "timeout: %d \n", time(nullptr));
    
    	// 接收數據超時
    	fd->gstate->lock();
    	if (fd->sstate == sock_state::ss_recv_triggered)
    	{
    		// 已經接收到數據了. 由接收到數據的線程處理
    		return;
    	}
    	else if (fd->sstate == sock_state::ss_waiting)
    	{
    		fd->sstate = sock_state::ss_timeout_triggered;
    		//CancelThreadpoolIo(fd->tpio);	// 已經超時了,也就不用再接收數據了吧.【此处如果使用该句,在下次的StartThreadpoolIo(fd->tpio)就会崩溃】
    	}	
    	fd->gstate->unlock();
    	
    	// 如果設置了超時處理機制就調用
    	if (fd->timeout_cb)
    	{
    		fd->timeout_cb(fd);
    	}	
    }
    
    // post recv event to tpio
    void post_recv(
    	netfd *cfd,
    	io_callback recv_cb,
    	break_callback	break_cb,
    	uint32_t timeout,
    	timeout_callback	timer_cb)
    {
    	cfd->io_cb = recv_cb;
    	cfd->io_type = iotype::io_recv;
    	
    	if (cfd ->tpio == nullptr)
    	{
    		_set_tpio(cfd);
    	}
    
    	StartThreadpoolIo(cfd->tpio);
    	int		tRtn = 0;
    	DWORD	flags = 0;
    	_reset_netfd_wsabuf(cfd);
    	tRtn = WSARecv(
    		cfd->sock,
    		&(cfd->wsabuf), 1,
    		nullptr,
    		&flags,
    		(LPOVERLAPPED)cfd,
    		nullptr);
    
    	int	tErrorCode = GetLastError();
    	if ((SOCKET_ERROR == tRtn) && (WSA_IO_PENDING != tErrorCode))
    	{
    		if (WSAENOTSOCK == tErrorCode || WSAENOTCONN == tErrorCode || WSAECONNRESET == tErrorCode)
    		{
    			// SOCKET 连接断开
    			logc(CT_RED, 0, "連接斷開(PC). \n");
    			_be_forced_over_conn(cfd);
    		}
    		else
    		{			
    			logc(CT_RED, CT_HIGHLIGHT, "SOCKET connection was aborted by the software. error code:%d \n", tErrorCode);
    			_be_forced_over_conn(cfd);
    		}
    
    		return;
    	}
    
    	if (timeout > 0)
    	{
    		assert(timer_cb != nullptr);	// 设置使用超时就要设置相应的超时回调函数
    
    		cfd->timeout_cb = timer_cb;
    		cfd->timeout = timeout;
    		cfd->sstate = sock_state::ss_using;		
    		if (cfd->tptimer == nullptr)
    		{
    			_set_tptimer(cfd);
    		}		
    		_start_tptimer(cfd);
    	}
    }


    emyueguang

    2014年11月13日 7:21
  • 就出现上面图片显示的这个错误,如果你有需要的话我可以把整个代码都发给你


    emyueguang

    2014年11月13日 7:22