bool TCPClient::Post(u8 *data, u32 data_bytes, u32 skip_bytes) { AsyncBuffer *buffer = AsyncBuffer::Promote(data); if (_disconnecting) { buffer->Release(); return false; } buffer->Reset(fastdelegate::MakeDelegate(this, &TCPClient::OnWrite)); WSABUF wsabuf; wsabuf.buf = reinterpret_cast<CHAR*>( data + skip_bytes ); wsabuf.len = data_bytes; AddRef(); // Fire off a WSASend() and forget about it int result = WSASend(_socket, &wsabuf, 1, 0, 0, buffer->GetOv(), 0); // This overlapped operation will always complete unless // we get an error code other than ERROR_IO_PENDING. if (result && WSAGetLastError() != ERROR_IO_PENDING) { FATAL("TCPClient") << "WSASend error: " << SocketGetLastErrorString(); buffer->Release(); ReleaseRef(); return false; } return true; }
bool TCPClient::ConnectEx(const NetAddr &remoteServerAddress) { // Get ConnectEx() interface GUID GuidConnectEx = WSAID_CONNECTEX; LPFN_CONNECTEX lpfnConnectEx; DWORD copied; if (WSAIoctl(_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GuidConnectEx), &lpfnConnectEx, sizeof(lpfnConnectEx), &copied, 0, 0)) { FATAL("TCPClient") << "Unable to get ConnectEx interface: " << SocketGetLastErrorString(); return false; } // Unwrap NetAddr NetAddr::SockAddr addr_out; int addr_len; if (!remoteServerAddress.Unwrap(addr_out, addr_len, _ipv6)) { FATAL("TCPClient") << "Unable to execute ConnectEx: Server address invalid"; return false; } // If unable to get an AsyncServerAccept object, AsyncBuffer *buffer; if (!AsyncBuffer::Acquire(buffer)) { FATAL("TCPClient") << "Out of memory: Unable to allocate ConnectEx overlapped structure"; return false; } buffer->Reset(fastdelegate::MakeDelegate(this, &TCPClient::OnConnectEx)); AddRef(); // Queue up a ConnectEx() BOOL result = lpfnConnectEx(_socket, reinterpret_cast<sockaddr*>( &addr_out ), addr_len, 0, 0, 0, buffer->GetOv()); // This overlapped operation will always complete unless // we get an error code other than ERROR_IO_PENDING. if (!result && WSAGetLastError() != ERROR_IO_PENDING) { FATAL("TCPClient") << "ConnectEx error: " << SocketGetLastErrorString(); buffer->Release(); ReleaseRef(); return false; } return true; }
bool UDPEndpoint::Post(const NetAddr &addr, u8 *data, u32 data_bytes, u32 skip_bytes) { AsyncBuffer *buffer = AsyncBuffer::Promote(data); if (_closing) { buffer->Release(); return false; } // Unwrap NetAddr object to something sockaddr-compatible NetAddr::SockAddr out_addr; int addr_len; if (!addr.Unwrap(out_addr, addr_len)) { buffer->Release(); return false; } WSABUF wsabuf; wsabuf.buf = reinterpret_cast<CHAR*>( data + skip_bytes ); wsabuf.len = data_bytes; buffer->Reset(fastdelegate::MakeDelegate(this, &UDPEndpoint::OnWriteComplete)); AddRef(); // Fire off a WSASendTo() and forget about it int result = WSASendTo(_socket, &wsabuf, 1, 0, 0, reinterpret_cast<const sockaddr*>( &out_addr ), addr_len, buffer->GetOv(), 0); // This overlapped operation will always complete unless // we get an error code other than ERROR_IO_PENDING. if (result && WSAGetLastError() != ERROR_IO_PENDING) { FATAL("UDPEndpoint") << "WSASendTo error: " << SocketGetLastErrorString(); buffer->Release(); ReleaseRef(); return false; } return true; }