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; }
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); }
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; }
//////////////////////////////////////////////////////////////////// // 投递接收数据请求 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; }
//////////////////////////////////////////////////////////////////// // 投递接收数据请求 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; }
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; } }
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); }
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; }
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 ; } } } }
/* * 异步接受包体 */ 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; }
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)); }
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; }
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); } } }
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; }
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"); }
// 投递接收数据请求 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; }
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 = >cpClt_OnReadWrite; pClient->pfnOnIocpError = >cpClt_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; } }
/** * \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; }
/*------------------------------------------------------------------------------------------------------------------ -- 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; }
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; }
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; } } }
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. } }
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; }
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; } }