net_ssize_t net_recvfrom( NET_SOCKET s, void *buf, size_t len, int flags, struct sockaddr* from, socklen_t *fromlen, int timeout ) { DWORD readbytes = 0; DWORD rflags = ( DWORD )flags; BOOL dwRes; DWORD selflags; WSABUF datadesc = { len, buf }; ResetEvent( s->o.hEvent ); if( WSARecvFrom( s->s, &datadesc, 1, &readbytes, &rflags, from, fromlen, &s->o, NULL ) == SOCKET_ERROR ) { if( WSAGetLastError() != WSA_IO_PENDING ) return 0; } else return readbytes; dwRes = WaitForSingleObject( s->o.hEvent, timeout == NET_INF_TIMEOUT ? INFINITE : timeout ); if( dwRes == WAIT_OBJECT_0 ) { if( !WSAGetOverlappedResult( s->s, &s->o, &readbytes, TRUE, &selflags ) ) readbytes = 0; } else if( dwRes == WAIT_TIMEOUT ) { WSAGetOverlappedResult( s->s, &s->o, &readbytes, TRUE, &selflags ); readbytes = 0; } return readbytes; }
// Finish receiving an UDP packet. Returns amount of bytes read, or 0 if nothing is read. int ioHelperFinishRecvFrom(struct s_io_handle *handle) { DWORD len; DWORD flags; len = 0; flags = 0; if(handle->ovlr_used) { if(WSAGetOverlappedResult(handle->fd, &handle->ovlr, &len, FALSE, &flags) == TRUE) { handle->ovlr_used = 0; ResetEvent(handle->ovlr.hEvent); if(len > 0) { handle->content_len = len; } } else { if(WSAGetLastError() != WSA_IO_INCOMPLETE) { handle->ovlr_used = 0; ResetEvent(handle->ovlr.hEvent); } } } if(len > 0) { return len; } else { return 0; } }
unsigned int SocketReceiver::GetReceiveResult() { if (m_resultPending) { DWORD flags = 0; if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags)) { if (m_lastResult == 0) m_eofReceived = true; } else { switch (WSAGetLastError()) { default: m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE); case WSAEDISCON: m_lastResult = 0; m_eofReceived = true; } } m_resultPending = false; } return m_lastResult; }
int ff_win_net_complete_overlapped_io(SOCKET socket, WSAOVERLAPPED *overlapped) { struct ff_fiber *current_fiber; int int_bytes_transferred = -1; BOOL result; DWORD flags; DWORD bytes_transferred; current_fiber = ff_fiber_get_current(); ff_win_completion_port_register_overlapped_data(net_ctx.completion_port, overlapped, current_fiber); ff_core_yield_fiber(); ff_win_completion_port_deregister_overlapped_data(net_ctx.completion_port, overlapped); result = WSAGetOverlappedResult(socket, overlapped, &bytes_transferred, FALSE, &flags); if (result != FALSE) { int_bytes_transferred = (int) bytes_transferred; } else { int last_error; last_error = WSAGetLastError(); ff_log_debug(L"the overlapped operation on the socket=%llu, overlapped=%p failed. WSAGetLastError()=%d", (uint64_t) socket, overlapped, last_error); } return int_bytes_transferred; }
static AJ_Status AJ_Net_Send(AJ_IOBuffer* buf) { DWORD ret; DWORD tx = AJ_IO_BUF_AVAIL(buf); AJ_InfoPrintf(("AJ_Net_Send(buf=0x%p)\n", buf)); assert(buf->direction == AJ_IO_BUF_TX); if (tx > 0) { NetContext* ctx = (NetContext*) buf->context; WSAOVERLAPPED ov; DWORD flags = 0; WSABUF wsbuf; memset(&ov, 0, sizeof(ov)); ov.hEvent = sendEvent; wsbuf.len = tx; wsbuf.buf = buf->readPtr; ret = WSASend(ctx->tcpSock, &wsbuf, 1, NULL, flags, &ov, NULL); if (!WSAGetOverlappedResult(ctx->tcpSock, &ov, &tx, TRUE, &flags)) { AJ_ErrPrintf(("AJ_Net_Send(): send() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError())); return AJ_ERR_WRITE; } buf->readPtr += tx; } if (AJ_IO_BUF_AVAIL(buf) == 0) { AJ_IO_BUF_RESET(buf); } AJ_InfoPrintf(("AJ_Net_Send(): status=AJ_OK\n")); return AJ_OK; }
/* event manager callback when reads are ready */ static void on_accept(void *arg, int success) { server_port *sp = arg; SOCKET sock = sp->new_socket; grpc_winsocket_callback_info *info = &sp->socket->read_info; grpc_endpoint *ep = NULL; if (success) { DWORD transfered_bytes = 0; DWORD flags; BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, &transfered_bytes, FALSE, &flags); if (!wsa_success) { char *utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message); gpr_free(utf8_message); closesocket(sock); } else { gpr_log(GPR_DEBUG, "on_accept: accepted connection"); ep = grpc_tcp_create(grpc_winsocket_create(sock)); } } else { gpr_log(GPR_DEBUG, "on_accept: shutting down"); closesocket(sock); gpr_mu_lock(&sp->server->mu); if (0 == --sp->server->active_ports) { gpr_cv_broadcast(&sp->server->cv); } gpr_mu_unlock(&sp->server->mu); } if (ep) sp->server->cb(sp->server->cb_arg, ep); start_accept(sp); }
static AJ_Status AJ_ARDP_UDP_Send(void* context, uint8_t* buf, size_t len, size_t* sent) { AJ_Status status = AJ_OK; DWORD ret; NetContext* ctx = (NetContext*) context; WSAOVERLAPPED ov; DWORD flags = 0; WSABUF wsbuf; memset(&ov, 0, sizeof(ov)); ov.hEvent = sendEvent; wsbuf.len = len; wsbuf.buf = buf; AJ_InfoPrintf(("AJ_ARDP_UDP_Send(buf=0x%p, len=%lu)\n", buf, len)); ret = WSASend(ctx->udpSock, &wsbuf, 1, NULL, flags, &ov, NULL); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_ARDP_UDP_Send(): WSASend() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError())); *sent = 0; return AJ_ERR_WRITE; } if (!WSAGetOverlappedResult(ctx->udpSock, &ov, sent, TRUE, &flags)) { AJ_ErrPrintf(("AJ_ARDP_UDP_Send(): WSAGetOverlappedResult() failed. WSAGetLastError()=0x%x, status=AJ_ERR_WRITE\n", WSAGetLastError())); return AJ_ERR_WRITE; } return status; }
static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, int from_iocp) { async_connect *ac = acp; SOCKET sock = ac->socket->socket; grpc_endpoint **ep = ac->endpoint; grpc_winsocket_callback_info *info = &ac->socket->write_info; grpc_closure *on_done = ac->on_done; grpc_timer_cancel(exec_ctx, &ac->alarm); gpr_mu_lock(&ac->mu); if (from_iocp) { DWORD transfered_bytes = 0; DWORD flags; BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, &transfered_bytes, FALSE, &flags); GPR_ASSERT(transfered_bytes == 0); if (!wsa_success) { char *utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); gpr_free(utf8_message); } else { *ep = grpc_tcp_create(ac->socket, ac->addr_name); ac->socket = NULL; } } async_connect_unlock_and_cleanup(ac); /* If the connection was aborted, the callback was already called when the deadline was met. */ on_done->cb(exec_ctx, on_done->cb_arg, *ep != NULL); }
void NetworkConnection::dataReceived() { if (!closed) // Ignore call if connection is closed { BOOL operationSucceeded = // Call receive WSAGetOverlappedResult(connection, &receiveOverlapped, &bytesReceived, FALSE, &flags); // If anything went wrong, didnt receive anything or // the send error flag was set if (!operationSucceeded || bytesReceived < 1 || sendError) { // If not blocking error if (WSAGetLastError() != WSA_IO_INCOMPLETE) close(); // Close connection else // If not, continue waiting continueReceive(); } else { // If receiver object associated, let them know data is if (dataReceiver != nullptr) // received dataReceiver->receivedData(receiveBuffer, (int)bytesReceived); continueReceive(); // wait for more data } } }
int WSARead(SOCKET sd, char * message, int timeout, int size){ WSAOVERLAPPED ov; DWORD recvBytes; DWORD recvErr; DWORD flags = 0; WSABUF dbuf; dbuf.buf = message; dbuf.len = size; ov.hEvent = WSACreateEvent(); if ((recvErr = WSARecv(sd, &dbuf, 1, &recvBytes,&flags, &ov, NULL)) == SOCKET_ERROR) { recvErr = WSAGetLastError(); if (recvErr != WSA_IO_PENDING) { return 0; } } recvErr = WSAWaitForMultipleEvents(1, &ov.hEvent, FALSE, timeout, FALSE); switch (recvErr) { case WAIT_TIMEOUT: return 0; break; case WAIT_FAILED: exit(1); break; default: break; } int x = strlen(dbuf.buf); int rc = WSAGetOverlappedResult(sd, &ov, &recvBytes, FALSE, &flags); return recvBytes; }
// Sends an IPv4 UDP packet. Returns length of sent message. static int ioSendUDPv4Packet(struct s_io_state *iostate, const unsigned char *buf, const int len, const struct s_io_v4addr *destination) { struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; memcpy(&addr.sin_addr.s_addr, destination->addr, 4); memcpy(&addr.sin_port, destination->port, 2); #ifdef IO_WINDOWS DWORD ret = 0; DWORD flags = 0; WSABUF wsabuf; wsabuf.buf = (char *)buf; wsabuf.len = len; WSASendTo(iostate->fd[IO_FDID_UDPV4SOCKET].fd, &wsabuf, 1, NULL, flags, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), &iostate->overlapped_write[IO_FDID_UDPV4SOCKET], NULL); WSAGetOverlappedResult(iostate->fd[IO_FDID_UDPV4SOCKET].fd, &iostate->overlapped_write[IO_FDID_UDPV4SOCKET], &ret, TRUE, &flags); #else int ret; ret = sendto(iostate->fd[IO_FDID_UDPV4SOCKET].fd, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); #endif if(ret > 0) { return ret; } else { return 0; } }
static void do_iocp_work() { BOOL success; DWORD bytes = 0; DWORD flags = 0; ULONG_PTR completion_key; LPOVERLAPPED overlapped; gpr_timespec wait_time = gpr_inf_future; grpc_winsocket *socket; grpc_winsocket_callback_info *info; void(*f)(void *, int) = NULL; void *opaque = NULL; success = GetQueuedCompletionStatus(g_iocp, &bytes, &completion_key, &overlapped, gpr_time_to_millis(wait_time)); if (!success && !overlapped) { /* The deadline got attained. */ return; } GPR_ASSERT(completion_key && overlapped); if (overlapped == &g_iocp_custom_overlap) { if (completion_key == (ULONG_PTR) &g_iocp_kick_token) { /* We were awoken from a kick. */ return; } gpr_log(GPR_ERROR, "Unknown custom completion key."); abort(); } socket = (grpc_winsocket*) completion_key; if (overlapped == &socket->write_info.overlapped) { info = &socket->write_info; } else if (overlapped == &socket->read_info.overlapped) { info = &socket->read_info; } else { gpr_log(GPR_ERROR, "Unknown IOCP operation"); abort(); } success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); if (socket->orphan) { grpc_winsocket_destroy(socket); gpr_atm_full_fetch_add(&g_orphans, -1); return; } info->bytes_transfered = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); GPR_ASSERT(overlapped == &info->overlapped); gpr_mu_lock(&socket->state_mu); GPR_ASSERT(!info->has_pending_iocp); if (info->cb) { f = info->cb; opaque = info->opaque; info->cb = NULL; } else { info->has_pending_iocp = 1; } gpr_mu_unlock(&socket->state_mu); if (f) f(opaque, 1); }
//sends a message, or part of one int CPassiveSock::Send(const void * const lpBuf, const int Len) { WSAOVERLAPPED os; WSABUF buffers[2]; WSAEVENT hEvents[2] = {NULL,NULL}; DWORD dwWait, bytes_sent=0, msg_flags = 0; // Setup up the events to wait on hEvents[1] = write_event; hEvents[0] = m_hStopEvent; // Setup the buffers array buffers[0].buf = (char *)lpBuf; buffers[0].len = Len; msg_flags = 0; dwWait = 0; int rc; LastError = 0; // Create the overlapped I/O event and structures memset(&os, 0, sizeof(OVERLAPPED)); os.hEvent = write_event; WSAResetEvent(read_event); rc = WSASend(ActualSocket, buffers, 1, &bytes_sent, 0, &os, NULL); LastError=WSAGetLastError(); if ((rc == SOCKET_ERROR) && (LastError == WSA_IO_PENDING)) // Write in progress { CTimeSpan TimeLeft = SendEndTime - CTime::GetCurrentTime(); dwWait = WaitForMultipleObjects(2, hEvents, false, (DWORD)TimeLeft.GetTotalSeconds()*1000); if (dwWait == WAIT_OBJECT_0+1) // I/O completed { if (WSAGetOverlappedResult(ActualSocket, &os, &bytes_sent, true, &msg_flags)) return bytes_sent; } } else if (!rc) // if rc is zero, the read was completed immediately { if (WSAGetOverlappedResult(ActualSocket, &os, &bytes_sent, true, &msg_flags)) return bytes_sent; } return SOCKET_ERROR; }
ConnectionPtr SocketConnection::acceptSync() { LB_TS_THREAD( _recvThread ); if( !isListening( )) return 0; LBASSERT( _overlappedAcceptData ); LBASSERT( _overlappedSocket != INVALID_SOCKET ); if( _overlappedSocket == INVALID_SOCKET ) return 0; // complete accept DWORD got = 0; DWORD flags = 0; if( !WSAGetOverlappedResult( _readFD, &_overlappedRead, &got, TRUE, &flags )) { LBWARN << "Accept completion failed: " << lunchbox::sysError << ", closing socket" << std::endl; close(); return 0; } sockaddr_in* local = 0; sockaddr_in* remote = 0; int localLen = 0; int remoteLen = 0; GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16, sizeof( sockaddr_in ) + 16, (sockaddr**)&local, &localLen, (sockaddr**)&remote, &remoteLen ); _tuneSocket( _overlappedSocket ); ConstConnectionDescriptionPtr description = getDescription(); SocketConnection* newConnection = new SocketConnection; ConnectionPtr connection( newConnection ); // to keep ref-counting correct newConnection->_readFD = _overlappedSocket; newConnection->_writeFD = _overlappedSocket; #ifndef _WIN32 //fcntl( _overlappedSocket, F_SETFL, O_NONBLOCK ); #endif newConnection->_initAIORead(); _overlappedSocket = INVALID_SOCKET; newConnection->_setState( STATE_CONNECTED ); ConnectionDescriptionPtr newDescription = newConnection->_getDescription(); newDescription->bandwidth = description->bandwidth; newDescription->port = ntohs( remote->sin_port ); newDescription->setHostname( getHostName( *remote )); LBDEBUG << "accepted connection from " << newDescription->getHostname() << ":" << newDescription->port << std::endl; return connection; }
/* GetQueuedCompletionStatus doesn't reliably yield WSA error codes, so * we use WSAGetOverlappedResult to translate. */ static void bev_async_set_wsa_error(struct bufferevent *bev, struct event_overlapped *eo) { DWORD bytes, flags; evutil_socket_t fd; fd = _evbuffer_overlapped_get_fd(bev->input); WSAGetOverlappedResult(fd, &eo->overlapped, &bytes, FALSE, &flags); }
unsigned int SocketSender::GetSendResult() { if (m_resultPending) { DWORD flags = 0; BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags); m_s.CheckAndHandleError("WSAGetOverlappedResult", result); m_resultPending = false; } return m_lastResult; }
static AJ_Status AJ_ARDP_UDP_Recv(void* context, uint8_t** data, uint32_t* recved, uint32_t timeout) { NetContext* ctx = (NetContext*) context; DWORD ret = SOCKET_ERROR; WSAEVENT events[2]; DWORD flags = 0; static uint8_t buffer[UDP_SEGBMAX]; *data = NULL; if (wsaOverlapped.hEvent == INVALID_HANDLE_VALUE) { wsbuf.len = sizeof(buffer); wsbuf.buf = buffer; memset(&wsaOverlapped, 0, sizeof(WSAOVERLAPPED)); wsaOverlapped.hEvent = recvEvent; ret = WSARecvFrom(ctx->udpSock, &wsbuf, 1, NULL, &flags, NULL, NULL, &wsaOverlapped, NULL); if ((ret == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING)) { AJ_ErrPrintf(("WSARecvFrom(): failed WSAGetLastError()=%d\n", WSAGetLastError())); return AJ_ERR_READ; } } events[0] = wsaOverlapped.hEvent; events[1] = interruptEvent; ret = WSAWaitForMultipleEvents(2, events, FALSE, timeout, TRUE); switch (ret) { case WSA_WAIT_EVENT_0: flags = 0; if (WSAGetOverlappedResult(ctx->udpSock, &wsaOverlapped, recved, TRUE, &flags)) { WSAResetEvent(wsaOverlapped.hEvent); wsaOverlapped.hEvent = INVALID_HANDLE_VALUE; *data = buffer; return AJ_OK; } else { AJ_ErrPrintf(("AJ_ARDP_UDP_Recv(): WSAGetOverlappedResult error; WSAGetLastError()=%d\n", WSAGetLastError())); return AJ_ERR_READ; } break; case WSA_WAIT_EVENT_0 + 1: WSAResetEvent(interruptEvent); return AJ_ERR_INTERRUPTED; case WSA_WAIT_TIMEOUT: return AJ_ERR_TIMEOUT; break; default: AJ_ErrPrintf(("AJ_ARDP_UDP_Recv(): WSAWaitForMultipleEvents error; WSAGetLastError()=%d\n", WSAGetLastError())); return AJ_ERR_READ; } }
int IOCPMonitor::GetError(SOCKET sock, WSAOVERLAPPED* pWSAOVERLAPPED) { #ifdef WIN32 DWORD dwTrans; DWORD dwFlags; if(FALSE == WSAGetOverlappedResult(sock, pWSAOVERLAPPED, &dwTrans, FALSE, &dwFlags)) return WSAGetLastError(); else return ERROR_SUCCESS; #endif return 0; }
void grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline) { BOOL success; DWORD bytes = 0; DWORD flags = 0; ULONG_PTR completion_key; LPOVERLAPPED overlapped; grpc_winsocket *socket; grpc_winsocket_callback_info *info; grpc_closure *closure = NULL; success = GetQueuedCompletionStatus( g_iocp, &bytes, &completion_key, &overlapped, deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type))); if (success == 0 && overlapped == NULL) { return; } GPR_ASSERT(completion_key && overlapped); if (overlapped == &g_iocp_custom_overlap) { gpr_atm_full_fetch_add(&g_custom_events, -1); if (completion_key == (ULONG_PTR)&g_iocp_kick_token) { /* We were awoken from a kick. */ return; } gpr_log(GPR_ERROR, "Unknown custom completion key."); abort(); } socket = (grpc_winsocket *)completion_key; if (overlapped == &socket->write_info.overlapped) { info = &socket->write_info; } else if (overlapped == &socket->read_info.overlapped) { info = &socket->read_info; } else { gpr_log(GPR_ERROR, "Unknown IOCP operation"); abort(); } success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); info->bytes_transfered = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); GPR_ASSERT(overlapped == &info->overlapped); GPR_ASSERT(!info->has_pending_iocp); gpr_mu_lock(&socket->state_mu); if (info->closure) { closure = info->closure; info->closure = NULL; } else { info->has_pending_iocp = 1; } gpr_mu_unlock(&socket->state_mu); grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL); }
OverlappedTransferBuffer *Socket::BeginSend(int maxBytesToSend) { if (!writeOpen) return 0; // See if the oldest one of the previously submitted transfers has now finished, // and reuse that buffer without allocating a new one, if so. #ifdef WIN32 if (queuedSendBuffers.Size() > 0) { OverlappedTransferBuffer *sentData = *queuedSendBuffers.Front(); DWORD flags = 0; BOOL ret = WSAGetOverlappedResult(connectSocket, &sentData->overlapped, (LPDWORD)&sentData->bytesContains, (queuedSendBuffers.CapacityLeft() == 0) ? TRUE : FALSE, &flags); int error = (ret == TRUE) ? 0 : Network::GetLastError(); if (ret == TRUE) { queuedSendBuffers.PopFront(); // If the buffer we pulled off was too small, free it and allocate a new one which is of the desired size. if (sentData->bytesAllocated < maxBytesToSend) { DeleteOverlappedTransferBuffer(sentData); return AllocateOverlappedTransferBuffer(maxBytesToSend); ///\todo In debug mode - track this pointer. } else { // The existing transfer buffer is large enough. Prepare it for reuse and pass back to caller. sentData->buffer.len = sentData->bytesAllocated; // This is the number of bytes that the client is allowed to fill. sentData->bytesContains = 0; // No bytes currently in use. return sentData; } } if (ret == FALSE && error != WSA_IO_INCOMPLETE) { LOG(LogError, "Socket::BeginSend: WSAGetOverlappedResult failed with an error %s, code %d != WSA_IO_INCOMPLETE!", Network::GetErrorString(error).c_str(), error); writeOpen = false; return 0; } } if (queuedSendBuffers.CapacityLeft() == 0) return 0; #endif // No previous send buffer has finished from use (or not using overlapped transfers) - allocate a new buffer. return AllocateOverlappedTransferBuffer(maxBytesToSend); }
int send_nblk( SOCKET s, char *buf, int len, int flags, unsigned int timeout, CTCPIPSystemDrvr* pTCPIPSystem) { unsigned long sflags = 0; int nLeft = len; int idx = 0; int retcode; long lastResult; DWORD written = 0; WSABUF wsabuf; WSAOVERLAPPED overlapped; SEND_INFO si; si.hEvent = pTCPIPSystem->m_hEvents[1]; si.s = s; si.timeout = timeout; overlapped.hEvent = pTCPIPSystem->m_hEvents[1]; while (nLeft > 0) { wsabuf.buf = &buf[idx]; wsabuf.len = nLeft; if (WSASend(s, &wsabuf, 1, &written, 0, &overlapped, NULL) == 0) { lastResult = written; } else { if (WSAGetLastError() != WSA_IO_PENDING) { (fpTCPIPSET_ERROR)((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_WRITE_READ, F_SEND, WSAGetLastError(), (int)0); return false; } retcode = wait_for_event(&si, FD_WRITE, pTCPIPSystem); if (retcode == 0) return false; if (FALSE==WSAGetOverlappedResult(s, &overlapped, &written, false, &sflags)) { (fpTCPIPSET_ERROR)((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_WRITE_READ, F_SEND_GETOVERLAPPEDRESULTS, WSAGetLastError(), (int)0); return false; } lastResult = written; } nLeft -= lastResult; idx += lastResult; } return idx; }
std::size_t TcpConnection::write(const uint8_t* data, size_t size) { assert(dispatcher != nullptr); assert(writeContext == nullptr); if (stopped) { throw InterruptedException(); } if (size == 0) { if (shutdown(connection, SD_SEND) != 0) { throw std::runtime_error("TcpConnection::write, shutdown failed, result=" + std::to_string(WSAGetLastError())); } return 0; } WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(const_cast<uint8_t*>(data))}; TcpConnectionContext context; context.hEvent = NULL; if (WSASend(connection, &buf, 1, NULL, 0, &context, NULL) != 0) { int lastError = WSAGetLastError(); if (lastError != WSA_IO_PENDING) { throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError)); } } context.context = GetCurrentFiber(); context.interrupted = false; writeContext = &context; dispatcher->dispatch(); assert(context.context == GetCurrentFiber()); assert(dispatcher != nullptr); assert(writeContext == &context); writeContext = nullptr; DWORD transferred; DWORD flags; if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) { int lastError = WSAGetLastError(); if (lastError != ERROR_OPERATION_ABORTED) { throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError)); } assert(context.interrupted); throw InterruptedException(); } assert(transferred == size); assert(flags == 0); return transferred; }
// Sends an UDP packet. Returns length of sent message. int ioHelperSendTo(struct s_io_handle *handle, const unsigned char *send_buf, const int send_buf_size, const struct sockaddr *destination_sockaddr, const socklen_t destination_sockaddr_len) { int len; #if defined(IO_LINUX) || defined(IO_BSD) len = sendto(handle->fd, send_buf, send_buf_size, 0, destination_sockaddr, destination_sockaddr_len); #elif defined(IO_WINDOWS) int ovlw_used; WSABUF wsabuf; DWORD flags; DWORD dwlen; len = 0; wsabuf.buf = (char *)send_buf; wsabuf.len = send_buf_size; flags = 0; ovlw_used = 0; if(WSASendTo(handle->fd, &wsabuf, 1, NULL, flags, destination_sockaddr, destination_sockaddr_len, &handle->ovlw, NULL) == 0) { ovlw_used = 1; } else { if(WSAGetLastError() == WSA_IO_PENDING) { ovlw_used = 1; } } if(ovlw_used) { if(WSAGetOverlappedResult(handle->fd, &handle->ovlw, &dwlen, TRUE, &flags) == TRUE) { len = dwlen; } ResetEvent(handle->ovlw.hEvent); } #else #error not implemented len = 0; #endif if(len > 0) { return len; } else { return 0; } }
ConnectionPtr PGMConnection::acceptSync() { EQ_TS_THREAD( _recvThread ); if( _state != STATE_LISTENING ) return 0; EQASSERT( _overlappedAcceptData ); EQASSERT( _overlappedSocket != INVALID_SOCKET ); if( _overlappedSocket == INVALID_SOCKET ) return 0; // complete accept DWORD got = 0; DWORD flags = 0; if( !WSAGetOverlappedResult( _readFD, &_overlapped, &got, TRUE, &flags )) { EQWARN << "Accept completion failed: " << base::sysError << ", closing connection" << std::endl; close(); return 0; } sockaddr_in* local = 0; sockaddr_in* remote = 0; int localLen = 0; int remoteLen = 0; GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16, sizeof( sockaddr_in ) + 16, (sockaddr**)&local, &localLen, (sockaddr**)&remote, &remoteLen ); PGMConnection* newConnection = new PGMConnection; ConnectionPtr connection( newConnection ); // to keep ref-counting correct newConnection->_readFD = _overlappedSocket; _overlappedSocket = INVALID_SOCKET; newConnection->_setupReadSocket(); newConnection->_writeFD = _writeFD; newConnection->_initAIORead(); newConnection->_state = STATE_CONNECTED; newConnection->_description = _description; EQINFO << "accepted connection " << (void*)newConnection << " from " << inet_ntoa( remote->sin_addr ) << ":" << ntohs( remote->sin_port ) << std::endl; return connection; }
void main(int argc,char**argv){ WSADATA wsaData; SOCKET sock; SOCKADDR_IN sendAddr; WSABUF dataBuf; char msg[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; int sendBytes=0; WSAEVENT eventObject; WSAOVERLAPPED overlapped; if(argc!=3){ printf("Usage : %s <IP> <PORT> \n",argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) ErrorHandling("WSAStartup error"); sock=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED); memset(&sendAddr,0,sizeof(sendAddr)); sendAddr.sin_family=AF_INET; sendAddr.sin_port=htons(atoi(argv[2])); sendAddr.sin_addr.s_addr=inet_addr(argv[1]); if(connect(sock,(SOCKADDR*)&sendAddr,sizeof(sendAddr))==SOCKET_ERROR) ErrorHandling("connect error"); eventObject=WSACreateEvent(); memset(&overlapped,0,sizeof(overlapped)); dataBuf.len=strlen(msg)+1; dataBuf.buf=msg; if(WSASend(sock,&dataBuf,1,&sendBytes,0,&overlapped,NULL)==SOCKET_ERROR){ if(WSAGetLastError()==WSA_IO_PENDING){ //전송할 데이터가 남아 있는 상태 puts("Background data send"); WSAWaitForMultipleEvents(1,&eventObject,TRUE,WSA_INFINITE,FALSE); WSAGetOverlappedResult(sock,&overlapped,&sendBytes,FALSE,NULL); } else ErrorHandling("WSASend error"); } printf("Send data size : %d \n",sendBytes); WSACloseEvent(eventObject); closesocket(sock); WSACleanup(); }
static void accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, int ok) { struct accepting_socket *as = EVUTIL_UPCAST(o, struct accepting_socket, overlapped); LOCK(&as->lev->base); EnterCriticalSection(&as->lock); if (ok) { /* XXXX Don't do this if some EV_MT flag is set. */ event_deferred_cb_schedule( event_base_get_deferred_cb_queue(as->lev->event_base), &as->deferred); LeaveCriticalSection(&as->lock); } else if (as->free_on_cb) { struct evconnlistener *lev = &as->lev->base; free_and_unlock_accepting_socket(as); listener_decref_and_unlock(lev); return; } else if (as->s == INVALID_SOCKET) { /* This is okay; we were disabled by iocp_listener_disable. */ LeaveCriticalSection(&as->lock); } else { /* Some error on accept that we couldn't actually handle. */ BOOL ok; DWORD transfer = 0, flags=0; event_sock_warn(as->s, "Unexpected error on AcceptEx"); ok = WSAGetOverlappedResult(as->s, &o->overlapped, &transfer, FALSE, &flags); if (ok) { /* well, that was confusing! */ as->error = 1; } else { as->error = WSAGetLastError(); } event_deferred_cb_schedule( event_base_get_deferred_cb_queue(as->lev->event_base), &as->deferred); LeaveCriticalSection(&as->lock); } UNLOCK(&as->lev->base); }
size_t TcpConnection::read(uint8_t* data, size_t size) { assert(dispatcher != nullptr); assert(readContext == nullptr); if (stopped) { throw InterruptedException(); } WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(data)}; DWORD flags = 0; TcpConnectionContext context; context.hEvent = NULL; if (WSARecv(connection, &buf, 1, NULL, &flags, &context, NULL) != 0) { int lastError = WSAGetLastError(); if (lastError != WSA_IO_PENDING) { throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError)); } } assert(flags == 0); context.context = GetCurrentFiber(); context.interrupted = false; readContext = &context; dispatcher->dispatch(); assert(context.context == GetCurrentFiber()); assert(dispatcher != nullptr); assert(readContext == &context); readContext = nullptr; DWORD transferred; if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) { int lastError = WSAGetLastError(); if (lastError != ERROR_OPERATION_ABORTED) { throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError)); } assert(context.interrupted); throw InterruptedException(); } assert(transferred <= size); assert(flags == 0); return transferred; }
grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline) { BOOL success; DWORD bytes = 0; DWORD flags = 0; ULONG_PTR completion_key; LPOVERLAPPED overlapped; grpc_winsocket *socket; grpc_winsocket_callback_info *info; success = GetQueuedCompletionStatus( g_iocp, &bytes, &completion_key, &overlapped, deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type))); if (success == 0 && overlapped == NULL) { return GRPC_IOCP_WORK_TIMEOUT; } GPR_ASSERT(completion_key && overlapped); if (overlapped == &g_iocp_custom_overlap) { gpr_atm_full_fetch_add(&g_custom_events, -1); if (completion_key == (ULONG_PTR)&g_iocp_kick_token) { /* We were awoken from a kick. */ return GRPC_IOCP_WORK_KICK; } gpr_log(GPR_ERROR, "Unknown custom completion key."); abort(); } socket = (grpc_winsocket *)completion_key; if (overlapped == &socket->write_info.overlapped) { info = &socket->write_info; } else if (overlapped == &socket->read_info.overlapped) { info = &socket->read_info; } else { abort(); } success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); info->bytes_transfered = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); GPR_ASSERT(overlapped == &info->overlapped); grpc_socket_become_ready(exec_ctx, socket, info); return GRPC_IOCP_WORK_WORK; }
bool Socket::IsOverlappedSendReady() { if (!writeOpen) return false; #ifdef WIN32 if (queuedSendBuffers.CapacityLeft() > 0) return true; OverlappedTransferBuffer *sentData = *queuedSendBuffers.Front(); DWORD flags = 0; BOOL ret = WSAGetOverlappedResult(connectSocket, &sentData->overlapped, (LPDWORD)&sentData->bytesContains, FALSE, &flags); return ret == TRUE; #else EventArray ea; ea.AddEvent(Event(connectSocket, EventWaitWrite)); return ea.Wait(0) == 0; #endif }
static void on_connect(void *acp, int success) { async_connect *ac = acp; SOCKET sock = ac->socket->socket; grpc_endpoint *ep = NULL; grpc_winsocket_callback_info *info = &ac->socket->write_info; void(*cb)(void *arg, grpc_endpoint *tcp) = ac->cb; void *cb_arg = ac->cb_arg; grpc_alarm_cancel(&ac->alarm); if (success) { DWORD transfered_bytes = 0; DWORD flags; BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, &transfered_bytes, FALSE, &flags); GPR_ASSERT(transfered_bytes == 0); if (!wsa_success) { char *utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); gpr_free(utf8_message); goto finish; } else { ep = grpc_tcp_create(ac->socket); goto finish; } } else { gpr_log(GPR_ERROR, "on_connect is shutting down"); goto finish; } abort(); finish: gpr_mu_lock(&ac->mu); if (!ep) { grpc_winsocket_orphan(ac->socket); } async_connect_cleanup(ac); cb(cb_arg, ep); }