Exemple #1
0
bool ClientSession::PostRecv() const
{
	if (!IsConnected())
		return false;

	OverlappedIOContext* recvContext = new OverlappedIOContext(this, IO_RECV);
	recvContext->mWsaBuf.len = BUFSIZE;
	recvContext->mWsaBuf.buf = recvContext->mBuffer;

	DWORD recvbytes = 0;
	DWORD flags = 0;

	if (SOCKET_ERROR ==
		WSARecv(mSocket, &(recvContext->mWsaBuf), 1, &recvbytes, &flags, (LPWSAOVERLAPPED)recvContext, NULL))
	{
		if (WSAGetLastError() != WSA_IO_PENDING)
			return false;
	}
	
	return true;
}
void CWin32Socket::Receive(TWin32Message& aMessage)
	{
	__ASSERT_DEBUG(iReceiveMessage == NULL, Panic(EWinSockPrtCWin32SocketMultipleReceiveRequests));
	iReceiveMessage = &aMessage;
	WSP_LOG(WspLog::Printf(_L("CWin32Socket::Receive: this: 0x%x, bytes to get: %d"), this, iReceiveMessage->WriteBuffer().MaxLength()));
	iReceiveBuffer.buf = reinterpret_cast<char*>(const_cast<TUint8*>(iReceiveMessage->WriteBuffer().Ptr()));
	iReceiveBuffer.len = iReceiveMessage->WriteBuffer().MaxLength();
	iFlags = 0;
	iReceiveOverlapped.hEvent = (void*) this;
	DWORD numberOfBytesReceived;
	TInt ret = WSARecv(iSocket, &iReceiveBuffer, 1, &numberOfBytesReceived, &iFlags, &iReceiveOverlapped, &ReceiveCompletion);
	if (ret == SOCKET_ERROR)
		{
		TInt err = WSAGetLastError();
		if (err != WSA_IO_PENDING)
			{
			WSP_LOG(WspLog::Printf(_L("\tsocket error: %d"), err));
			Complete(iReceiveMessage, MapWinSockError(err));
			}
		}
	}
bool NetSocket::PostRecv()
{
    _netStatus.fetch_or(NET_STATUS_RECV_PENDING);

    NetIoBuffer* recvOP = new NetIoBuffer(NetCompletionOP::OP_READ);
    recvOP->Reset(GetSocket());

    MemoryBlock* buffer = recvOP->Alloc(MAX_PACKET_SIZE);

    WSABUF wbuf;
    wbuf.buf = buffer->GetData();
    wbuf.len = buffer->GetDataLen();

    DWORD flags = 0;
    int rc = WSARecv(
        GetSocket(),
        &wbuf,
        1,
        NULL,
        &flags,
        &(recvOP->ol),
        NULL
    );

    if (rc == SOCKET_ERROR)
    {
        int error = WSAGetLastError();
        if (error != WSA_IO_PENDING)
        {
            delete recvOP;

            DebugPrint("PostRecv: WSARecv* failed: %s", SocketGetErrorString(error).c_str());
            Disconnect(NET_CTYPE_SYSTEM);

            return false;
        }
    }

    return true;
}
Exemple #4
0
void HttpSocket::OnReceive(int error_code)
{
	if(error_code!=0)
	{
		p_parent->ReportStatus(this,m_ip,m_port,error_code);
		return;
	}

	if(m_receiving_socket_data || m_receiving_some_socket_data)
	{
		ContinueToReceiveSocketData();
		return;
	}

	ReceiveSomeSocketData(4096);

	//
	// Check to see if there is any more data waiting to be read. KLUDGE (???)
	//

	char buf[1];

	WSABUF wsabuf;
	wsabuf.buf=buf;
	wsabuf.len=1;

	DWORD num_read=0;
	DWORD flags=MSG_PEEK;	// this variable is both an input and an output
	
	int ret=WSARecv(m_hSocket,&wsabuf,1,&num_read,&flags,NULL,NULL);

	if(ret!=SOCKET_ERROR)
	{
		if(num_read!=0)
		{
			OnReceive(0);	// bring on the recursion
		}
	}

}
JNIEXPORT jint JNICALL
Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
                                      jlong address, jint len)
{
    /* set up */
    int i = 0;
    DWORD read = 0;
    DWORD flags = 0;
    jint fd = fdval(env, fdo);
    WSABUF buf;

    /* destination buffer and size */
    buf.buf = (char *)address;
    buf.len = (u_long)len;

    /* read into the buffers */
    i = WSARecv((SOCKET)fd, /* Socket */
            &buf,           /* pointers to the buffers */
            (DWORD)1,       /* number of buffers to process */
            &read,          /* receives number of bytes read */
            &flags,         /* no flags */
            0,              /* no overlapped sockets */
            0);             /* no completion routine */

    if (i == SOCKET_ERROR) {
        int theErr = (jint)WSAGetLastError();
        if (theErr == WSAEWOULDBLOCK) {
            return IOS_UNAVAILABLE;
        }
        if (theErr == WSAECONNRESET) {
            purgeOutstandingICMP(env, clazz, fd);
            JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException", 0);
            return IOS_THROWN;
        }
        JNU_ThrowIOExceptionWithLastError(env, "Write failed");
        return IOS_THROWN;
    }

    return convertReturnVal(env, (jint)read, JNI_TRUE);
}
Exemple #6
0
int TSocket::Receive(void *buf,unsigned int buf_len)
{
	WSABUF wsabuf;
	wsabuf.buf=(char *)buf;
	wsabuf.len=buf_len;

	DWORD num_read;
	DWORD flags=0;	// this variable is both an input and an output
	
	int ret=WSARecv(m_hSocket,&wsabuf,1,&num_read,&flags,NULL,NULL);

	if(ret==SOCKET_ERROR)
	{
		return SOCKET_ERROR;
	}
	else
	{
		return (int)num_read;
	}

	return ret;
}
Exemple #7
0
////////////////////////////////////////////////////////////////////
// 投递接收数据请求
bool CIOCPModel::_PostRecv( PER_IO_CONTEXT* pIoContext )
{
	// 初始化变量
	DWORD dwFlags = 0;
	DWORD dwBytes = 0;
	WSABUF *p_wbuf   = &pIoContext->m_wsaBuf;
	OVERLAPPED *p_ol = &pIoContext->m_Overlapped;

	pIoContext->ResetBuffer();
	pIoContext->m_OpType = RECV_POSTED;

	// 初始化完成后,,投递WSARecv请求
	int nBytesRecv = WSARecv( pIoContext->m_sockAccept, p_wbuf, 1, &dwBytes, &dwFlags, p_ol, NULL );

	// 如果返回值错误,并且错误的代码并非是Pending的话,那就说明这个重叠请求失败了
	if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
	{
		//this->_ShowMessage("投递第一个WSARecv失败!");
		return false;
	}
	return true;
}
Exemple #8
0
////////////////////////////////////////////////////////////////////
// 投递接收数据请求
bool IocpPool::_PostRecv( IoContent* pIoContext )
{
	// 初始化变量
	DWORD dwFlags = 0;
	DWORD dwBytes = 0;
	WSABUF *p_wbuf   = &pIoContext->m_wsaBuf;
	OVERLAPPED *p_ol = &pIoContext->overlapped;

	pIoContext->ResetBuffer();
	pIoContext->optype = RECV_POSTED;
	if (!pIoContext->socket) return false;
	// 初始化完成后,,投递WSARecv请求
	int nBytesRecv = WSARecv( pIoContext->socket->getHandle().getHandle(), p_wbuf, 1, &pIoContext->msgLen, &dwFlags, p_ol, NULL );

	// 如果返回值错误,并且错误的代码并非是Pending的话,那就说明这个重叠请求失败了
	if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
	{
		//this->_ShowMessage("投递第一个WSARecv失败!");
		return false;
	}
	return true;
}
Exemple #9
0
int IOCP_RealRecv(IOCP* iocp, IOCP_CONTEXT* context)
{
	DWORD dwTransfered = 0;
	DWORD dwLastError = 0;
	DWORD dwFlags = 0;
	WSABUF wsaBuf;
	SOCKET socket = INVALID_SOCKET;

	if(context->type == IOCP_HANDLE_SOCKET)
	{
		wsaBuf.len = context->readOlp.len;
		wsaBuf.buf = (char*)(context->readOlp.buf);

		socket = (SOCKET)(context->handle);
		if(SOCKET_ERROR == WSARecv(socket, &wsaBuf, 1, &dwTransfered, &dwFlags, (LPWSAOVERLAPPED)(&context->readOlp), NULL))
		{
			dwLastError = WSAGetLastError();
			if(dwLastError != WSA_IO_PENDING)
			{
				iocp->lastErrorCode = dwLastError;
				return IOCP_UNDEFINED;
			}
		}
		return IOCP_PENDING;
	}
	else
	{
		if(!ReadFile(context->handle, context->readOlp.buf, context->readOlp.len, &dwTransfered, (LPOVERLAPPED)(&context->readOlp)))
		{
			dwLastError = GetLastError();
			if(dwLastError != ERROR_IO_PENDING)
			{
				iocp->lastErrorCode = dwLastError;
				return IOCP_UNDEFINED;
			}
		}
		return IOCP_PENDING;
	}
}
Exemple #10
0
JNIEXPORT jint JNICALL
Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
                                       jlong address, jint len)
{
    /* set up */
    int i = 0;
    DWORD read = 0;
    DWORD flags = 0;
    jint fd = fdval(env, fdo);
    WSABUF buf;

    /* limit size */
    if (len > MAX_BUFFER_SIZE)
        len = MAX_BUFFER_SIZE;

    /* destination buffer and size */
    buf.buf = (char *)address;
    buf.len = (u_long)len;

    /* read into the buffers */
    i = WSARecv((SOCKET)fd, /* Socket */
                &buf,           /* pointers to the buffers */
                (DWORD)1,       /* number of buffers to process */
                &read,          /* receives number of bytes read */
                &flags,         /* no flags */
                0,              /* no overlapped sockets */
                0);             /* no completion routine */

    if (i == SOCKET_ERROR) {
        int theErr = (jint)WSAGetLastError();
        if (theErr == WSAEWOULDBLOCK) {
            return IOS_UNAVAILABLE;
        }
        JNU_ThrowIOExceptionWithLastError(env, "Read failed");
        return IOS_THROWN;
    }

    return convertReturnVal(env, (jint)read, JNI_TRUE);
}
Exemple #11
0
bool wsa_recv_empty(socket_t fd, WSAOVERLAPPED& ovl)
{
	DWORD bytes = 0;
	DWORD flags = 0;
	WSABUF ws_buf = { 0, &s_zero };

	memset(&ovl, 0, sizeof(ovl));
	int ret = WSARecv(fd, &ws_buf, 1, &bytes, &flags, &ovl, nullptr);
	if (ret == 0)
	{
		return true;
	}
	else if (ret == SOCKET_ERROR)
	{
		int err = get_socket_error();
		if (err == WSA_IO_PENDING)
		{
			return true;
		}
	}
	return false;
}
Exemple #12
0
void CIOCPServer::PostRecv(ClientContext* pContext)
{
	// issue a read request 
	OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IORead);
	ULONG			ulFlags = MSG_PARTIAL;
	DWORD			dwNumberOfBytesRecvd;
	UINT nRetVal = WSARecv(pContext->m_Socket, 
		&pContext->m_wsaInBuffer,
		1,
		&dwNumberOfBytesRecvd, 
		&ulFlags,
		&pOverlap->m_ol, 
		NULL);

	DWORD dwErr = WSAGetLastError();


	if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING) 
	{
		RemoveStaleClient(pContext, FALSE);
	}
}
ssize_t
ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
{
    int           rc;
    u_long        bytes, flags;
    WSABUF        wsabuf[1];
    ngx_err_t     err;
    ngx_event_t  *rev;

    wsabuf[0].buf = (char *) buf;
    wsabuf[0].len = size;
    flags = 0;
    bytes = 0;

    rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);

    ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
                   "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);

    rev = c->read;

    if (rc == -1) {
        rev->ready = 0;
        err = ngx_socket_errno;

        if (err == WSAEWOULDBLOCK) {
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
                           "WSARecv() not ready");
            return NGX_AGAIN;
        }

        rev->error = 1;
        ngx_connection_error(c, err, "WSARecv() failed");

        return NGX_ERROR;
    }

    return bytes;
}
static bool RequestReadNotification(IOOperation* ioop)
{
	DWORD	numBytes, flags;
	WSABUF	wsabuf;
	IODesc*	iod;
	int		ret;

//	Log_Trace("fd.index = %d", ioop->fd.index);

	iod = GetIODesc(ioop->fd);

	assert(iod->read == NULL);

	wsabuf.buf = NULL;
	wsabuf.len = 0;

	flags = 0;
	memset(&iod->ovlRead, 0, sizeof(OVERLAPPED));

	if (ioop->type == UDP_READ)
		flags |= MSG_PEEK;	// without this, the O/S would discard each incoming UDP packet
							// as it doesn't fit into the user-supplied (0 length) buffer

	ret = WSARecv(ioop->fd.sock, &wsabuf, 1, &numBytes, &flags, &iod->ovlRead, NULL);
	if (ret == SOCKET_ERROR)
	{
		ret = WSAGetLastError();
		if (ret != WSA_IO_PENDING)
		{
			Log_Trace("%d", ret);
			return false;
		}
	}

	iod->read = ioop;
	ioop->active = true;

	return true;
}
VOID AcceptThread(LPVOID)
{
	LPPER_HANDLE_DATA PerHandleData;
	LPPER_IO_DATA PerIoData;
	SOCKET clientSock;
	DWORD Flags,RecvBytes;
	while(1)
	{
		clientSock = accept(hSocket,NULL, NULL);
		if(clientSock == INVALID_SOCKET)
		{
			cout << "Error!! accept()" << endl;
			return ;
		}


		PerHandleData = (LPPER_HANDLE_DATA)new(PER_HANDLE_DATA);
		g_sockArr[g_clientNum++] = PerHandleData->hSocket = clientSock;

		CreateIoCompletionPort((HANDLE)clientSock, CompletionPort, 
			(DWORD)PerHandleData,0);

		PerIoData = (LPPER_IO_DATA) new PER_IO_DATA;
		ZeroMemory(&(PerIoData->overlapped), sizeof(OVERLAPPED));
		PerIoData->wsaBuf.len = sizeof(DATA);
		PerIoData->wsaBuf.buf = (char*)&PerIoData->data;
		Flags = 0;

		if(WSARecv(clientSock, &(PerIoData->wsaBuf), 1, &RecvBytes,
			&Flags, &(PerIoData->overlapped), NULL) == SOCKET_ERROR)
		{
			if(WSAGetLastError( ) != ERROR_IO_PENDING)
			{
				cout << "Error!! WSARecv()" << endl;
				return ;
			}
		}
	}
}
Exemple #16
0
/*
* 异步接受包体
*/
bool CConnect::AsyncRecvBody()
{
	DWORD	flags = 0;
	DWORD	recvBytes = 0;

	//ZeroMemory( &m_iIO, sizeof( m_iIO ) );
	m_iIO.type = IO_READ_BODY;

	m_iIO.dataBuf.buf = m_iIO.buffer + m_iIO.usIOSize;
	u_short diff = m_iIO.hdr.usMsgLen - m_iIO.usIOSize;
	m_iIO.dataBuf.len = RECV_SIZE > diff ? diff : RECV_SIZE;

	if ( WSARecv( m_socket, &m_iIO.dataBuf, 1, &recvBytes, &flags, &m_iIO.overlapped, NULL ) == SOCKET_ERROR )
	{
		if ( ERROR_IO_PENDING != WSAGetLastError() )
		{
			return false;
		}
	}

	return true;
}
Exemple #17
0
void NET_BaseSocket::PrivateOnReceived()
{
	if (!m_created)
		return;
	DWORD to_read, received = 0, flags = 0, space;
	OP( ioctlsocket(m_socket, FIONREAD, &to_read), "NET_BaseSocket::PrivateOnReceived, ioctlsocket" );
	bool repeat = to_read > m_in_buf_size;
	if (repeat)
		to_read = m_in_buf_size;
	m_in_wsa_buf.buf = m_in_buf;
	m_in_wsa_buf.len = to_read;
	m_last_error = 0;
	OP2( WSARecv(m_socket, &m_in_wsa_buf, 1, &received, &flags, m_read_thread.GetOverlapped(), NULL), m_last_error != WSA_IO_PENDING, "NET_BaseSocket::PrivateOnReceived, WSARecv" );
	if (m_last_error == WSA_IO_PENDING)
	{
		LOG_V0_AddMessage(LOG_V0_DEBUG_MESSAGE, TXT("%s::PrivateOnReceived -- PENDING") << GetName());
		WSAResetEvent(m_read_thread.GetOverlapped()->hEvent);
		return;
	}
	{
		MutexWrap in_write_access(m_in_data->m_w_mutex);
		{
			MutexWrap in_read_access(m_in_data->m_r_mutex);
			space = m_in_data->SpaceFor(RingBuffer_WRITE);
		}
		if (space < received)
			OnError("NET_BaseSocket::PrivateOnReceived -- space < received !!!");
		else
		{
			LOG_V0_AddMessage(LOG_V0_DEBUG_MESSAGE, TXT("%s -- получено %d") << GetName() << received);
			m_in_data->Write(m_in_buf, received);
		}
	}

	OnReceived();
	if (repeat || received < to_read)
		WSASetEvent(m_read_thread.Event(0));
}
Exemple #18
0
static void begin_zero_byte_read(iocpdesc_t *iocpd)
{
  if (iocpd->read_in_progress) return;
  if (iocpd->read_closed) {
    pni_events_update(iocpd, iocpd->events | PN_READABLE);
    return;
  }

  read_result_t *result = iocpd->read_result;
  memset(&result->base.overlapped, 0, sizeof (OVERLAPPED));
  DWORD flags = 0;
  WSABUF wsabuf;
  wsabuf.buf = result->unused_buf;
  wsabuf.len = 0;
  int rc = WSARecv(iocpd->socket, &wsabuf, 1, NULL, &flags,
                       &result->base.overlapped, 0);
  if (rc && WSAGetLastError() != ERROR_IO_PENDING) {
    iocpdesc_fail(iocpd, WSAGetLastError(), "IOCP read error");
    return;
  }
  iocpd->ops_in_progress++;
  iocpd->read_in_progress = true;
}
Exemple #19
0
static void  after_sent(PER_HANDLE_DATA* handle_data)
{
    int error;
    DWORD bytes = 0;
    DWORD flag = 0;

    assert(handle_data);
    memset(&handle_data->overlap, 0, sizeof(handle_data->overlap));
    handle_data->wsbuf.len = kDefaultBufferSize;
    handle_data->opertype =  OperRecv;
    error = WSARecv(handle_data->socket, &handle_data->wsbuf, 1, &bytes,
        &flag, &handle_data->overlap, NULL);
    if (error == SOCKET_ERROR)
    {
        error = WSAGetLastError();
        if (error != WSA_IO_PENDING)
        {
            fprintf(stderr, "WSARecv() failed, socket: %d, %d: %s", handle_data->socket,
                error, LAST_ERROR_MSG);
            on_close(handle_data);
        }
    }
}
Exemple #20
0
int aio_socket_recv_v(aio_socket_t socket, socket_bufvec_t* vec, int n, aio_onrecv proc, void* param)
{
	DWORD flags = 0;
	DWORD dwBytes = 0;
	struct aio_context *ctx = (struct aio_context*)socket;
	struct aio_context_action *aio;

	aio = util_alloc(ctx);
	aio->action = iocp_recv;
	aio->recv.proc = proc;
	aio->recv.param = param;

	if(SOCKET_ERROR == WSARecv(ctx->socket, vec, n, &dwBytes, &flags, &aio->overlapped, NULL))
	{
		DWORD ret = WSAGetLastError();
		if(WSA_IO_PENDING != ret)
		{
			util_free(aio);
			return ret;
		}
	}
	return 0;
}
Exemple #21
0
void
gas_start_reading (gas_client_info *ci)
{
	DWORD flags=0, bytes=0;

	gas_trim_buffer (ci->rb);
	GAS_CI_SET_MARK_AT_TAIL (ci->rb);

	if (ci->overlapped!=NULL) {
		memset(ci->overlapped, 0, sizeof(WSAOVERLAPPED));
		ci->operation = GAS_OP_READ;
	}
	WSABUF wsabuf = { GAS_CI_GET_FREE_SPACE(ci->rb), GAS_CI_GET_DATA_TAIL(ci->rb) };

	if (WSARecv(ci->socket, &wsabuf, 1, &bytes, &flags, (WSAOVERLAPPED *)ci->overlapped, NULL) == SOCKET_ERROR) {
		ci->error = GAS_TRUE;
		int err = WSAGetLastError();
		if (err != WSA_IO_PENDING && err != WSAECONNABORTED)
			gas_error_message ("Error %d in WSARecv\n", err);
	}
	else
		gas_debug_message (GAS_IO, "Immediate read\n");
}
Exemple #22
0
// 投递接收数据请求
bool ServerContext::_PostRecv(IoContext* ioCtx)
{
	// 初始化变量
	DWORD dwFlags = 0;
	DWORD dwBytes = 0;
	//PackBuf p_wbuf ;
	PackBuf *p_wbuf = &(ioCtx->packBuf);
	OVERLAPPED *p_ol = &ioCtx->overlapped;

	ResetBuffer(ioCtx);//ioCtx->ResetBuffer();
	ioCtx->postIoType = POST_IO_RECV;

	// 初始化完成后,投递WSARecv请求
	int nBytesRecv = WSARecv(ioCtx->sock, p_wbuf, 1, &dwBytes, &dwFlags, p_ol, NULL);

	if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
	{
		//LOG4CPLUS_ERROR(log.GetInst(), "投递WSARecv失败!");
		return false;
	}

	return true;
}
Exemple #23
0
void GTcpClt_OnConnected(DWORD dwBytes, PGHND_DATA pClient, PGIO_DATA pIoData)
{
	setsockopt(pClient->Socket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
	pClient->hsState = GHND_STATE_CONNECTED;
	pClient->dwTickCountAcitve = GetTickCount();
	pClient->pfnOnIocpOper = &GTcpClt_OnReadWrite;
	pClient->pfnOnIocpError = &GTcpClt_OnReadWriteError;

	pfnOnGSockConnectClt((DWORD)pClient, pIoData->cData, dwBytes);

	ZeroMemory(pIoData, sizeof(WSAOVERLAPPED));
	DWORD dwCount = dwGSockNumberPostRecv;
	for(;;)
	{
		GIoDat_ResetIoDataOnRead(pIoData);
		pIoData->WSABuf.len = dwGSockRecvBytes;
		dwBytes = 0;
		DWORD dwFlag = 0;
		if((SOCKET_ERROR == WSARecv(pClient->Socket, &(pIoData->WSABuf), 1, &dwBytes, &dwFlag, LPWSAOVERLAPPED(pIoData), NULL)) &&
			(ERROR_IO_PENDING != WSAGetLastError()))
		{
			GTcpClt_OnReadWriteError(pClient, pIoData);
			return;
		}		
		dwCount--;
		if(!dwCount)
			return;
		pIoData = GIoDat_Alloc();
		if(!pIoData)
		{
			GLog_Write("GTcpClt_OnConnected:连接后,申请IoData失败");
			return;
		}
		pIoData->OperType = GIO_READ_COMPLETED;
		pIoData->pOwner = pClient;
	}
}
Exemple #24
0
/**
 * \brief The Windows implementation of readv() socket helper function.
 * \param fd the socket descriptor to read the data.
 * \param iov the iovector to store the data.
 * \param iovcnt number of element that should be filled.
 * \param addr if not NULL it considers using a UDP socket, otherwise it
 * considers using a TCP one.
 * \param addr_size pointer on address size, will be filled by this function.
 * \return number of bytes read or -1 if error.
 * \warning this function work only with socket!
 */
static ssize_t net_sock_readv_win(int fd, const struct iovec *iov,
    size_t iovcnt, const struct sockaddr* addr, socklen_t* addr_size)
{
  WSABUF winiov[iovcnt];
  DWORD winiov_len = iovcnt;
  size_t i = 0;
  DWORD ret = 0;

  if(iovcnt > sizeof(winiov))
  {
    return -1;
  }

  for(i = 0 ; i < iovcnt ; i++)
  {
    winiov[i].len = iov[i].iov_len;
    winiov[i].buf = iov[i].iov_base;
  }

  if(addr) /* UDP case */
  {
    if(WSARecvFrom(fd, winiov, winiov_len, &ret, NULL, (struct sockaddr*)addr,
          addr_size, NULL, NULL) != 0)
    {
      return -1;
    }
  }
  else /* TCP case */
  {
    if(WSARecv(fd, winiov, winiov_len, &ret, NULL, NULL, NULL) != 0)
    {
      return -1;
    }
  }

  return (ssize_t)ret;
}
Exemple #25
0
/*------------------------------------------------------------------------------------------------------------------
--      FUNCTION: process_header
--
--      DATE: Febuary 6 2014
--      REVISIONS: none
--
--      DESIGNER: Ramzi Chennafi
--      PROGRAMMER: Ramzi Chennafi
--
--      INTERFACE: int process_header(HWND hwnd, SOCKET recv), takes the parent HWND as an argument and the socket the header was sent to.
--
--      RETURNS: void
--
--      NOTES:
--      Retrieves the header datagram from the passed in socket. If using TCP, just grabs it. If on UDP, the header is grabbed then
--		acknowledged. If no header is successfully grabbed, the function is called on every WM_SOCKET message until it is.
----------------------------------------------------------------------------------------------------------------------*/
int process_header(HWND hwnd, SOCKET recv){

	SETTINGS * st = (SETTINGS*)GetClassLongPtr(hwnd, 0);
	DWORD RecvBytes = 0, Flags = 0;
	int status, server_len;
	struct	sockaddr_in server;

	char msg[MAX_SIZE];
	char * hdBuffer = (char*)malloc(sizeof(char)* HEADER_SIZE);
	memset(hdBuffer, 0, HEADER_SIZE);

	LPWSABUF wsaBuffer = (LPWSABUF)malloc(sizeof(WSABUF));
	wsaBuffer->len = HEADER_SIZE;
	wsaBuffer->buf = hdBuffer;

	if (st->protocol == TCP){
		if ((status = WSARecv(recv, wsaBuffer, 1, &RecvBytes, &Flags, NULL, NULL)) == SOCKET_ERROR){
			sprintf_s(msg, "Error %d in TCP WSARecv(header) with return of %d\n", WSAGetLastError(), status);
			activity(msg, EB_STATUSBOX);
		}

		if (wsaBuffer->buf[0] != ';'){ // I really should have used an uncommon character here
			return -1;
		}
	}
	else{
		server_len = sizeof(server);
		if ((status = WSARecvFrom(st->server_socket, wsaBuffer, 1, &RecvBytes, &Flags, (struct sockaddr *)&server, &server_len, NULL, NULL)) == SOCKET_ERROR){
			return -1;
		}
		acknowledge(hwnd);
	}

	grab_header_info(hdBuffer);
	return 1;
}
Exemple #26
0
DWORD WINAPI WorkThread(_In_  LPVOID lpParameter)
{
	HANDLE hCompletionPort = (HANDLE)lpParameter;
	DWORD dwBytesTransferred;
	pPerHandleData pHandleData = NULL;
	pPerIoData pIoData = NULL;
	LPOVERLAPPED pOverLapped = NULL;
	DWORD dwRecv = 0;
	DWORD dwFlag = 0;

	while (true)
	{
		if (!GetQueuedCompletionStatus(hCompletionPort, &dwBytesTransferred, (PULONG_PTR)&pHandleData, &pOverLapped, INFINITE))
		{
			printf_s("Get Completion Status Error: %ld\n", GetLastError());
		}
		pIoData = CONTAINING_RECORD(pOverLapped, PerIoData, OverLapped);

		if (dwBytesTransferred == 0)
		{
			closesocket(pHandleData->socket);
			delete pHandleData;
			delete pIoData;
			continue;
		}

		printf_s("Receive: %s\n", pIoData->Buffer);

		ZeroMemory((void*)(&pIoData->OverLapped), sizeof(pIoData->OverLapped));
		pIoData->wsaBuf.buf = pIoData->Buffer;
		pIoData->wsaBuf.len = DEFAULT_BUFLEN;
		pIoData->OprationType = 0;
		WSARecv(pHandleData->socket, &pIoData->wsaBuf, 1, &dwRecv, &dwFlag, &pIoData->OverLapped, NULL);
	}
	return 0;
}
Exemple #27
0
void CALLBACK WorkerRoutine(DWORD error, DWORD bytesTrans, LPWSAOVERLAPPED overlap, DWORD flags){
	DWORD sendBytes,recvBytes;
	if(error != 0 || bytesTrans == 0){
		//发生错误 关闭套接字
		closesocket(sNew);
		return;
	}
	//此时 一个重叠的wsarecv成功完成
	//现在可以接收数据
	memcpy(buff,buff + 1,bytesTrans - 1);  //收到的第一位为数据的编码标识 在此去除
	buff[bytesTrans - 1] = '\0';
	printf("recv data: %s \n", dataBuff.buf);
	//处理完成后 需要投递另外一个重叠的WSARecv 或 WSASend
	flags = 0;
	ZeroMemory(overlap,sizeof(WSAOVERLAPPED));
	dataBuff.len = BUFF_SIZE;
	dataBuff.buf = buff;
	if(WSARecv(sNew,&dataBuff,1,&recvBytes,&flags,overlap,WorkerRoutine) == SOCKET_ERROR){
		if(WSAGetLastError() != WSA_IO_PENDING){
			printf("WSARecv() failed with error %d \n", WSAGetLastError());
			return;
		}
	}
}
Exemple #28
0
void Server::PostRecv(Client* client)
{
    assert(client);

    WSABUF recvBufferDescriptor;
    recvBufferDescriptor.buf = reinterpret_cast<char*>(client->GetRecvBuff());
    recvBufferDescriptor.len = Client::MAX_RECV_BUFFER;

    DWORD numberOfBytes = 0;
    DWORD recvFlags = 0;

    IOEvent* event = IOEvent::Create(IOEvent::RECV, client);
    assert(event);

    StartThreadpoolIo(client->GetTPIO());

    if (WSARecv(client->GetSocket(), &recvBufferDescriptor, 1, &numberOfBytes, &recvFlags,
                &event->GetOverlapped(), NULL) == SOCKET_ERROR)
    {
        int error = WSAGetLastError();

        if (error != ERROR_IO_PENDING)
        {
            CancelThreadpoolIo(client->GetTPIO());

            ERROR_CODE(error, "WSARecv() failed.");

            OnClose(event);
            IOEvent::Destroy(event);
        }
    }
    else
    {
        // In this case, the completion callback will have already been scheduled to be called.
    }
}
Exemple #29
0
bool 
EasyIocp::PostRecv(CompTransmitKey *transKey, bool reset/* = true*/)
{
	EasyIocpBuffer *iocpBuffer = transKey->GetBuffer();
	if(reset)
		iocpBuffer->Reset();

	WSABUF* pBuf = iocpBuffer->GetWSABuf();
	SOCKET transSock = transKey->GetSocket();
	OVERLAPPED *pOv = transKey->GetOverlapped();
	DWORD transBytes = 0, flags = 0;
	int ret;

	//投递recv
	transKey->SetOperType(operRecv);

	ret = WSARecv(transSock, pBuf, 1, &transBytes, &flags, pOv, NULL);
	if(ret == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING) {
		print("EasyIocp::PostRecv: WSARecv failed.");
		return false;
	}

	return true;
}
Exemple #30
0
void Socket::EnqueueNewReceiveBuffer(OverlappedTransferBuffer *buffer)
{
	if (!readOpen || queuedReceiveBuffers.CapacityLeft() == 0 || IsUDPSlaveSocket())
	{
		DeleteOverlappedTransferBuffer(buffer); // buffer may be a zero pointer, but that is alright.
		return;
	}

	if (!buffer)
	{
		const int receiveBufferSize = 16384; // This is best to be at least 9K (the largest size of jumbo datagrams commonly supported)
		buffer = AllocateOverlappedTransferBuffer(receiveBufferSize);
		if (!buffer)
		{
			LOG(LogError, "Socket::EnqueueNewReceiveBuffer: Call to AllocateOverlappedTransferBuffer failed!");
			return;
		}
	}

	if (WSAResetEvent(buffer->overlapped.hEvent) != TRUE)
		LOG(LogError, "Socket::EnqueueNewReceiveBuffer: WSAResetEvent failed!");

	unsigned long flags = 0;
	int ret;

	if (IsUDPServerSocket())
	{
		buffer->fromLen = sizeof(buffer->from);
		ret = WSARecvFrom(connectSocket, &buffer->buffer, 1, (LPDWORD)&buffer->bytesContains, &flags, (sockaddr*)&buffer->from, &buffer->fromLen, &buffer->overlapped, 0);
	}
	else
	{
		ret = WSARecv(connectSocket, &buffer->buffer, 1, (LPDWORD)&buffer->bytesContains, &flags, &buffer->overlapped, 0);
	}

	int error = (ret == 0) ? 0 : Network::GetLastError();
	if (ret == 0 || (ret == SOCKET_ERROR && error == WSA_IO_PENDING)) // If ret is not 0, ret == SOCKET_ERROR according to MSDN. http://msdn.microsoft.com/en-us/library/ms741688(VS.85).aspx
	{
		if (ret == 0 && buffer->bytesContains == 0)
		{
            // Urho3D: only close TCP sockets upon receiving 0 bytes
            if (transport == SocketOverTCP && readOpen)
            {
                LOG(LogInfo, "Socket::EnqueueNewReceiveBuffer: Received 0 bytes from the network. Read connection closed in socket %s.", ToString().c_str());
                readOpen = false;
            }
			DeleteOverlappedTransferBuffer(buffer);
			return;
		}
		// Return value 0: The operation completed and we have received new data. Push it to a queue for the user to receive.
		// WSA_IO_PENDING: The operation was successfully enqueued.
		bool success = queuedReceiveBuffers.Insert(buffer);
		if (!success)
		{
			LOG(LogError, "Socket::EnqueueNewReceiveBuffer: queuedReceiveBuffers.Insert(buffer); failed!");
			DeleteOverlappedTransferBuffer(buffer);
		}
	}
	else if (error == WSAEDISCON)
	{
		if (IsUDPServerSocket())
			LOG(LogError, "Unexpected: Received WSAEDISCON on a UDP server socket!");

		LOG(LogError, "Socket::EnqueueNewReceivebuffer: WSAEDISCON. Connection closed in socket %s.", ToString().c_str());
		readOpen = false;
		///\todo Should do writeOpen = false; here as well?
		DeleteOverlappedTransferBuffer(buffer);
		return;
	}
	else
	{
		if (error != WSAEWOULDBLOCK && error != 0)
		{
			LOG(LogError, "Socket::EnqueueNewReceiveBuffer: %s for overlapped socket %s failed! Error: %s.", IsUDPServerSocket() ? "WSARecvFrom" : "WSARecv", ToString().c_str(), Network::GetErrorString(error).c_str());

			// We never close the server socket as a reaction on any error, since an error on one client could shut down
			// the whole server for all clients. This check is mainly here to ignore the 10054 error (WSAECONNRESET) which
			// is returned when UDP clients give back a ICMP Host Unreachable message, but since there may be other
			// client-specific errors, we don't explicitly check for the 10054 case only.
			if (!IsUDPServerSocket())
			{
				LOG(LogError, "Socket::EnqueueNewReceiveBuffer: Closing down socket.",  Network::GetErrorString(error).c_str());
				readOpen = false;
				writeOpen = false;
				Close();
			}
		}

		DeleteOverlappedTransferBuffer(buffer); // We failed to queue the buffer, free it up immediately to avoid leaking memory.
		return;
	}
}