/** receive until timeout happends **/ int receiveFromSockUtilTimeout(int sockFd, struct timeval *timeout) { //receive until no data from the other side for 10 seconds int sec = timeout->tv_sec; int usec = timeout->tv_usec; int recvLen = 0; char buffer[1024] = {0}; while (1) { if (waitForRead(sockFd, timeout) != 1) { break; } memset(buffer, 0, sizeof buffer); int tempLen = recvFromSock(sockFd, buffer, sizeof buffer - 1, 1); if (tempLen > 0) { recvLen += tempLen; } else { break; } timeout->tv_sec = sec; timeout->tv_usec = usec; } return recvLen; }
int CCTCPSocket::receiveData(void* buf, int size) { // basic checking if(buf == NULL || size <= 0) { return -1; } if (m_sock == kCCSocketInvalid) { return -1; } // read can be more than buffer size size = MIN(size, kCCSocketInputBufferDefaultSize); // ensure the packet is complete, if not, read again if (size > m_inBufLen) { if (!recvFromSock()) { return -1; } } // check available size = MIN(size, m_inBufLen); // if the packet is looped, need copy two times if(m_inBufStart + size > kCCSocketInputBufferDefaultSize) { int copylen = kCCSocketInputBufferDefaultSize - m_inBufStart; memcpy(buf, m_inBuf + m_inBufStart, copylen); memcpy((unsigned char *)buf + copylen, m_inBuf, size - copylen); } else { memcpy(buf, m_inBuf + m_inBufStart, size); } // reposition read pos m_inBufStart = (m_inBufStart + size) % kCCSocketInputBufferDefaultSize; m_inBufLen -= size; return size; }
/** used by thread to process new request*/ void * processRequest(void * param) { RequestInfo *requestInfo = (RequestInfo *) param; int sockFd = requestInfo->sockFd; char *clientIP = requestInfo->clientIP; int clientPort = requestInfo->clientPort; printf("start to serve request from %s:%d\n", clientIP, clientPort); //receive request file information char requestFile[1024] = {0}; int recvStatus = recvFromSock(sockFd, requestFile, sizeof requestFile - 1, 1); if (recvStatus < 0) { printf("recv request info failed\n"); closeSock(sockFd); free(requestInfo); return NULL; } else if (recvStatus == 0) { printf("client has closed this connection\n"); closeSock(sockFd); free(requestInfo); return NULL; } printf("requestInfo: %s\n", requestFile); // check File existence and open file if (!checkFileExist(requestFile)) { printf("file doesn't exist: %s\n", requestFile); closeSock(sockFd); free(requestInfo); return NULL; } FILE * fd = fopen(requestFile, "r"); if (!fd) { printf("open request file failed\n"); goto cleanAndQuit; } // send requested file char buffer[1024]; unsigned int requestFileSize = getFileSize(requestFile); unsigned int readSize = 0; unsigned int sentSize = 0; printf("start to send to client\n"); while (readSize < requestFileSize) { unsigned int tempReadLen = 0; memset(buffer, 0, sizeof buffer); if ((tempReadLen = fread(buffer, sizeof(char), sizeof buffer -1, fd)) < 0) { printf("read file failed %d\n", tempReadLen); goto cleanAndQuit; } readSize += tempReadLen; //send to socket if (sendToSock(sockFd, buffer, tempReadLen, 1) != 1) { printf("send to sock failed\n"); goto cleanAndQuit; } sentSize += tempReadLen; //printf("send to client with len %d, sumLen, %d\n", sumSentLen, sentSize); if (canRead(sockFd) != 1) { continue; } printf("start to receive cancel/close msg\n"); memset(buffer, 0, sizeof buffer); int recvLen = recvFromSock(sockFd, buffer, sizeof buffer - 1, 1); if (recvLen <= 0) {// the other side has close the sockfd or some error happens printf("failed to recv close/cancel signal\n"); goto cleanAndQuit; } printf("sent %d KB data\n", sentSize / 1024); printf("receive cancel/close msg: %s\n", buffer); if (strcmp(buffer, CANCEL_MSG) == 0) { printf("wait for close after receiving cancel msg\n"); if (waitForClose(sockFd) == 1) { printf("client close connection, quit right now\n"); } else { printf("waitForClose Failed, quit right now\n"); } } else { printf("close after receiving close msg\n"); } cleanAndQuit: closeSock(sockFd); if (requestInfo) { free(requestInfo); } if (fd) { fclose(fd); } return NULL; } }