Пример #1
0
/* static */ void CALLBACK
Server::IoCompletionCallback(PTP_CALLBACK_INSTANCE /* Instance */, PVOID /* Context */,
                             PVOID Overlapped, ULONG IoResult, ULONG_PTR NumberOfBytesTransferred,
                             PTP_IO /* Io */)
{
    IOEvent* event = CONTAINING_RECORD(Overlapped, IOEvent, GetOverlapped());
    assert(event);

    if (IoResult != ERROR_SUCCESS)
    {
        ERROR_CODE(IoResult, "I/O operation failed. type[%d]", event->GetType());

        switch (event->GetType())
        {
        case IOEvent::SEND:
            Server::Instance()->OnSend(event, NumberOfBytesTransferred);
            break;
        }

        Server::Instance()->OnClose(event);
    }
    else
    {
        switch (event->GetType())
        {
        case IOEvent::ACCEPT:
            Server::Instance()->OnAccept(event);
            break;

        case IOEvent::RECV:
            if (NumberOfBytesTransferred > 0)
            {
                Server::Instance()->OnRecv(event, NumberOfBytesTransferred);
            }
            else
            {
                Server::Instance()->OnClose(event);
            }
            break;

        case IOEvent::SEND:
            Server::Instance()->OnSend(event, NumberOfBytesTransferred);
            break;

        default:
            assert(false);
            break;
        }
    }

    IOEvent::Destroy(event);
}
Пример #2
0
void aysnc_accept(SOCKET sl, SOCKET sa, char * recvbuff, boost::function<void() > acceptcallback){
	DWORD bytes = 0;

	overlappedaccept * poverlappedaccept = static_cast<overlappedaccept*>(GetOverlapped(event_accept));
	poverlappedaccept->fncallback = acceptcallback;
	BOOL bret = AcceptEx(sl, sa, recvbuff, 0, sizeof(SOCKADDR_IN6), sizeof(SOCKADDR_IN6), &bytes, &(poverlappedaccept->ovlap));
	if (!bret){
		int err = WSAGetLastError();
		if (err != ERROR_IO_PENDING){
			throw exception::AcceptException("AcceptEx fail", err);
		}
	}
}
Пример #3
0
void async_disconnect(SOCKET s){
	LPFN_DISCONNECTEX DisConnectEx;
	DWORD bytes = 0;

	GUID guid = WSAID_DISCONNECTEX;
	if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &DisConnectEx, sizeof(DisConnectEx), &bytes, 0, 0) != 0){
		throw exception::DisConnectException("Get LPFN_DISCONNECTEX fail", GetLastError());
	}

	overlappeddisconnect * poverlappeddisconnect = static_cast<overlappeddisconnect*>(GetOverlapped(event_disconnect));
	poverlappeddisconnect->s = s;
	if (!DisConnectEx(s, &poverlappeddisconnect->ovlap, 0, 0)){
		throw exception::DisConnectException("DisConnectEx fail", GetLastError());
	}
}
Пример #4
0
void async_recvfrom(SOCKET s, char * buff, const uint32_t buflen, boost::function<void(char * buff, uint32_t len, const address & addr) > recvfromcallback){
	WSABUF * pWSABUF = GetWSABUF(1);
	pWSABUF->buf = buff;
	pWSABUF->len = buflen;

	overlappedrecvfrom * poverlappedrecvfrom = static_cast<overlappedrecvfrom*>(GetOverlapped(event_recv));
	poverlappedrecvfrom->fncallback = boost::bind(recvfromcallback, buff, _1, _2);
	
	DWORD bytes = 0;
	if (SOCKET_ERROR == WSARecvFrom(s, pWSABUF, 1, &bytes, 0, (sockaddr*)&poverlappedrecvfrom->remoteaddr, &poverlappedrecvfrom->addrlen, &poverlappedrecvfrom->ovlap, 0)){
		int err = WSAGetLastError();
		if (err != ERROR_IO_PENDING){
			throw exception::RecvfromException("Recvfrom fail", err);
		}
	}
}
Пример #5
0
void async_recv(SOCKET s, char * buff, const uint32_t buflen, boost::function<void(char * buff, uint32_t recvlen) > recvcallback){
	WSABUF * pWSABUF = GetWSABUF(1);
	pWSABUF->buf = buff;
	pWSABUF->len = buflen;

	overlappedrecv * poverlappedrecv = static_cast<overlappedrecv*>(GetOverlapped(event_recv));
	poverlappedrecv->fncallback = boost::bind(recvcallback, buff, _1);

	DWORD bytes = 0;
	if (SOCKET_ERROR == WSARecv(s, pWSABUF, 1, &bytes, 0, &(poverlappedrecv->ovlap), 0)){
		int err = WSAGetLastError();
		if (err != ERROR_IO_PENDING){
			throw exception::RecvException("Recv fail", err);
		}
	}
}
Пример #6
0
void async_connect(SOCKET s, const sockaddr * addr, boost::function<void() > connectcallback){
	LPFN_CONNECTEX ConnectEx;
	DWORD bytes = 0;

	GUID guid = WSAID_CONNECTEX;
	if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &ConnectEx, sizeof(ConnectEx), &bytes, 0, 0) != 0){
		throw exception::ConnectException("Get LPFN_CONNECTEX fail", GetLastError());
	}

	overlappedconnect * poverlappedconnect = static_cast<overlappedconnect*>(GetOverlapped(event_connect));
	poverlappedconnect->fncallback = connectcallback;
	if (!ConnectEx(s, addr, sizeof(addr), 0, 0, &bytes, &(poverlappedconnect->ovlap))){
		int err = WSAGetLastError();
		if (err != ERROR_IO_PENDING){
			throw exception::ConnectException("ConnectEx fail", err);
		}
	}
}
Пример #7
0
void async_send(SOCKET s, const std::vector<buffstruct> & buff, boost::function<void() > sendcallback){
	overlappedsend * poverlapped = static_cast<overlappedsend*>(GetOverlapped(event_send));

	WSABUF * pWSABUF = GetWSABUF(buff.size());
	for(uint32_t i = 0; i < buff.size(); i++){
		pWSABUF[i].buf = buff[i].buff;
		pWSABUF[i].len = buff[i].len;
	}
	poverlapped->vectbuff.assign(buff.begin(), buff.end());
	poverlapped->fncallback = sendcallback;

	DWORD bytes;
	if (SOCKET_ERROR == WSASend(s, pWSABUF, buff.size(), &bytes, 0, &poverlapped->ovlap, 0)){
		int err = WSAGetLastError();
		if (err != ERROR_IO_PENDING){
			throw exception::SendException("Send fail", err);
		}
	}
}
Пример #8
0
/// Accepts an incoming connection on a server pipe.
///
/// @param[in] timeout maximum time to wait for a client in milliseconds
/// @return this end of a pipe connected to the client, or NULL if none was available
CNamedPipe *CNamedPipe::Accept (unsigned long timeout) {
	assert (IsServer ());
#ifdef _WIN32
	if (!ConnectNamedPipe (GetFile (), GetOverlapped ())) {
		if (GetLastError () != ERROR_PIPE_CONNECTED) {
			if (!WaitOnOverlapped (timeout)) {
				DWORD dwError = GetLastError ();
				LOGWARN (TEXT ("Overlapped result not available, error ") << dwError);
				SetLastError (dwError);
				return NULL;
			}
		}
	}
	HANDLE handle = _CreatePipe (GetName (), IsServer (), false, IsReader ());
	if (!handle) {
		DWORD dwError = GetLastError ();
		LOGWARN (TEXT ("Couldn't create replacement pipe for server, error ") << dwError);
		SetLastError (dwError);
		return NULL;
	}
	CNamedPipe *poClient = new CNamedPipe (GetFile (), GetName (), false, IsReader ());
	SetFile (handle);
	return poClient;
#else
failedOperation:
	struct sockaddr_un addr;
	bool bLazyWait = false;
	unsigned long lLazy = IsLazyClosing ();
	if (lLazy) {
		bLazyWait = true;
		timeout = lLazy;
	}
timeoutOperation:
	int sock;
	if (BeginOverlapped (timeout, true)) {
		socklen_t len = sizeof (addr);
		sock = accept (GetFile (), (struct sockaddr*)&addr, &len);
		EndOverlapped ();
	} else {
		sock = -1;
	}
	if (sock < 0) {
		int ec = GetLastError ();
		if (ec == EINTR) {
			LOGDEBUG (TEXT ("Accept interrupted"));
			lLazy = IsLazyClosing ();
			if (lLazy) {
				if (bLazyWait) {
					LOGINFO (TEXT ("Closing file on idle timeout"));
					Close ();
				}
			}
			if (!IsClosed () && !bLazyWait) {
				bLazyWait = true;
				timeout = lLazy;
				LOGDEBUG (TEXT ("Resuming operation with idle timeout of ") << timeout << TEXT ("ms"));
				goto timeoutOperation;
			}
		}
		LOGWARN (TEXT ("Couldn't accept client, error ") << ec);
		SetLastError (ec);
		return NULL;
	}
	LOGINFO (TEXT ("Connection accepted on ") << GetName ());
	if (!_SetDefaultSocketOptions (sock)) {
		int ec = GetLastError ();
		close (sock);
		LOGWARN (TEXT ("Couldn't set default socket options, error ") << ec);
		SetLastError (ec);
		return NULL;
	}
	if ((send (sock, "!", 1, 0) != 1) || fcntl (sock, F_SETFL, O_NONBLOCK)) {
		int ec = GetLastError ();
		close (sock);
		if (ec == EPIPE) {
			LOGWARN (TEXT ("Client disconnected before receiving handshake"));
			goto failedOperation;
		}
		LOGWARN (TEXT ("Couldn't send handshake message, error ") << ec);
		SetLastError (ec);
		return NULL;
	} else {
		LOGDEBUG (TEXT ("Handshake message written"));
	}
	return new CNamedPipe (sock, GetName (), false, IsReader ());
#endif
}