void CIocpServer::OnNewConnection( SOCKET sock, char* addr ) { CIocpSocket* newclient = AllocSocket( ); newclient->m_Lock.Enter( ); newclient->m_Socket = sock; strcpy( newclient->m_Ip, addr ); m_ClientsLock.Enter( ); int sid = m_Clients.Append( newclient ); newclient->m_Index = sid; m_Iocp.Link( (HANDLE)sock, (void*)sid ); newclient->Start( ); m_ClientsLock.Leave( ); newclient->m_Lock.Leave( ); };
static __inline__ int raw_NET2_TCPConnectToIP(IPaddress *ip) { int s = -1; s = AllocSocket(TCPClientSocket); if (-1 == s) { setError("NET2: out of memory", -1); return -1; } socketHeap[s]->s.tcpSocket = snTCPOpen(ip); if (NULL == socketHeap[s]->s.tcpSocket) { setError("NET2: can't open a socket", -1); FreeSocket(s); return -1; } socketHeap[s]->state = addState; return s; }
static __inline__ int raw_NET2_TCPAcceptOnIP(IPaddress *ip) { int s = -1; s = AllocSocket(TCPServerSocket); if (-1 == s) { setError("NET2: out of memory", -1); return -1; } socketHeap[s]->s.tcpSocket = snTCPOpen(ip); if (NULL == socketHeap[s]->s.tcpSocket) { setError("NET2: can't open a socket", -1); FreeSocket(s); return -1; } socketHeap[s]->p.tcpPort = ip->port; socketHeap[s]->state = addState; return s; }
static __inline__ int raw_NET2_UDPAcceptOn(int port, int size) { int s = -1; s = AllocSocket(UDPServerSocket); if (-1 == s) { setError("NET2: out of memory", s); return -1; } socketHeap[s]->s.udpSocket = snUDPOpen(port); if (NULL == socketHeap[s]->s.udpSocket) { setError("NET2: can't open a socket", s); FreeSocket(s); return -1; } socketHeap[s]->p.udpLen = size; socketHeap[s]->state = addState; return s; }
static int PumpNetworkEvents(void *nothing) { int i = 0; #define timeOut (10) while (!doneYet) { if (-1 == snCheckSockets(socketSet, timeOut)) { setError("NET2: the CheckSockets call failed", -1); } lockData(); while ((!doneYet) && waitForRead) { waitUntilRead(); } for (i = 0; ((!doneYet) && (i < lastHeapSocket)); i++) { if (addState == socketHeap[i]->state) { switch(socketHeap[i]->type) { case unusedSocket: sendError("NET2: trying to add an unused socket", i); break; case TCPServerSocket: case TCPClientSocket: if (-1 != snTCPAddSocket(socketHeap[i]->s.tcpSocket)) { socketHeap[i]->state = readyState; } else { socketHeap[i]->state = delState; sendError("NET2: can't add a TCP socket to the socket set", i); } break; case UDPServerSocket: if (-1 != snUDPAddSocket(socketHeap[i]->s.udpSocket)) { socketHeap[i]->state = readyState; } else { socketHeap[i]->state = delState; sendError("NET2: can't add a UDP socket to the socket set", i); } break; default: sendError("NET2: invalid socket type, this should never happen", i); break; } } else if (delState == socketHeap[i]->state) { switch(socketHeap[i]->type) { case unusedSocket: sendError("NET2: trying to delete an unused socket", i); break; case TCPServerSocket: case TCPClientSocket: if (-1 == snTCPDelSocket(socketHeap[i]->s.tcpSocket)) { sendError("NET2: can't delete a TCP socket from the socket set", i); } snTCPClose(socketHeap[i]->s.tcpSocket); FreeSocket(i); break; case UDPServerSocket: if (-1 == snUDPDelSocket(socketHeap[i]->s.udpSocket)) { sendError("NET2: can't delete a UDP socket from the socket set", i); } snUDPClose(socketHeap[i]->s.udpSocket); FreeSocket(i); break; default: sendError("NET2: invalid socket type, this should never happen", i); break; } } else if ((TCPServerSocket == socketHeap[i]->type) && (snSocketReady(socketHeap[i]->s.genSocket))) { TCPsocket socket = NULL; socket = snTCPAccept(socketHeap[i]->s.tcpSocket); if (NULL != socket) { int s = -1; s = AllocSocket(TCPClientSocket); if (-1 != s) { //printf("got a connection!\n"); socketHeap[s]->s.tcpSocket = socket; socketHeap[s]->state = addState; sendEvent(NET2_TCPACCEPTEVENT, s, socketHeap[i]->p.tcpPort); } else // can't handle the connection, so close it. { snTCPClose(socket); sendError("NET2: a TCP accept failed", i); // let the app know } } } else if ((TCPClientSocket == socketHeap[i]->type) && (readyState == socketHeap[i]->state) && (snSocketReady(socketHeap[i]->s.genSocket))) { int len; CharQue *tb = &socketHeap[i]->q.tb; if (tcpQueLen <= tb->len) { waitForRead = 1; } else { len = snTCPRead(socketHeap[i]->s.tcpSocket, &tb->buf[tb->len], tcpQueLen - tb->len); if (0 < len) { int oldlen = tb->len; tb->len += len; if (0 == oldlen) { sendEvent(NET2_TCPRECEIVEEVENT, i, -1); } } else // no byte, must be dead. { socketHeap[i]->state = dyingState; sendEvent(NET2_TCPCLOSEEVENT, i, -1); } } } else if ((UDPServerSocket == socketHeap[i]->type) && (readyState == socketHeap[i]->state) && (snSocketReady(socketHeap[i]->s.genSocket))) { int recv = 0; UDPpacket *p = NULL; PacketQue *ub = &socketHeap[i]->q.ub; if (PacketQueFull(ub)) { waitForRead = 1; } else { while ((!PacketQueFull(ub)) && (NULL != (p = snUDPAllocPacket(socketHeap[i]->p.udpLen))) && (1 == (recv = snUDPRecv(socketHeap[i]->s.udpSocket, p)))) { if (PacketQueEmpty(ub)) { EnquePacket(ub, &p); sendEvent(NET2_UDPRECEIVEEVENT, i, -1); } else { EnquePacket(ub, &p); } } // unravel terminating conditions and free left over memory // if we need to if (!PacketQueFull(ub)) // if the packet que is full then everything is fine { if (NULL != p) // couldn't alloc a packet { if (0 >= recv) // ran out of packets { snUDPFreePacket(p); } } else { sendError("NET2: out of memory", i); } } } } } unlockData(); } return 0; }