////////////////////////////////////////////////////////////// // Read until EOM reached ////////////////////////////////////////////////////////////// bool CMimeProtocol::readEOM(int link,CHARPTR pszBuffer,CHARPTR pszTerminator,int maxSize) { char *pszTerm; int nReceived = 0; int nBytes = 0; // Reset strcpy(pszBuffer,""); // Forever while(!(pszTerm = strstr(pszBuffer,pszTerminator))){ // Receive bytes from socket nBytes = recvTcp(link,&pszBuffer[nReceived],maxSize-nReceived); // Check for end if(nBytes == 0) return false; // Check for error if(nBytes <= -1) continue; // Check limits if(nReceived + nBytes >= maxSize) return false; nReceived += nBytes; } return true; }
int main(int argc, char *argv[]) { int sfd_client = initTcpClient(IP, PORT); printf("connect success!\n"); Msg msg; while (memset(&msg, 0, sizeof(Msg)), fgets(msg.buf, MSG_SIZE, stdin) != NULL) { msg.len = strlen(msg.buf); sendTcp(sfd_client, &msg, msg.len + 4); memset(&msg, 0, sizeof(Msg)); recvTcp(sfd_client, &msg, 4); recvTcp(sfd_client, msg.buf, msg.len); write(1, msg.buf, strlen(msg.buf)); } memset(&msg, 0, sizeof(Msg)); sendTcp(sfd_client, &msg, 4 + msg.len); close(sfd_client); return 0; }
////////////////////////// // Receive ASCII (term) ////////////////////////// bool CMimeProtocol::receive(int link,char *pszBuffer,int nMaxSize,char *pszTerminator) { char szTmpBuffer[CBUFF_MASSIVE]; char *pszTerm; int nBytes = 0; int nReceived = 0; // Reset strcpy(pszBuffer,""); // Forever while(!(pszTerm = strstr(pszBuffer,pszTerminator))){ // Receive bytes from socket //nBytes = recvTcp(link,&szTmpBuffer[nReceived],nMaxSize-nReceived); nBytes = recvTcp(link,&pszBuffer[nReceived],nMaxSize-nReceived); if(nBytes == -1){ if(OSALASTERROR != OSAWOULDBLOCK) return false; OSASleep(5); continue; } // Check for end if(nBytes == 0 || nBytes == -1) return false; // Check for error if(nBytes <= -1) return false; // Copy data szTmpBuffer[nBytes] = 0; // Check limits if(nReceived + nBytes >= nMaxSize) return false; nReceived += nBytes; } // Success (remove terminator) pszBuffer[minimal(nReceived,nMaxSize)]=0; //*pszTerm = 0; return true; }
////////////////////////// // Read header & possible body ////////////////////////// bool CMimeProtocol::readMimeRequest(int link,CHARPTR *storage,int nMaxSize) { int read=0; int bytes; // Allocate initial buffer CHARPTR pszBuffer; pszBuffer = *storage = coms->Links[link].buffer; nMaxSize = coms->Links[link].limit; while(true){ // Read next lot if((bytes = recvTcp(link,&pszBuffer[read],nMaxSize-read)) < 0) return false; // Remote disconnect if(bytes == 0) return false; read+=bytes; // Check for header & body CHARPTR ptrHeadEnd=strstr(pszBuffer,"\r\n\r\n"); CHARPTR ptrContLen=strstr(pszBuffer,"Content-Length: "); int contentLength; // No header yet if(!ptrHeadEnd) return false; // Header & no-body required if(!ptrContLen){ *ptrHeadEnd=0; return true; } // Get body length if(!strparse(ptrContLen,"Content-Length: %1d",&contentLength)) return false; // Compare strlen of body int bodyLen = (ptrHeadEnd+=4)-pszBuffer; // Re-allocate for biggies if(contentLength > nMaxSize){ // Catch potential memory errors try{ // Re-alloc & copy current data to new buffer coms->Links[link].buffer = *storage = new CHAR[nMaxSize=(contentLength+nMaxSize)]; coms->Links[link].limit = nMaxSize; //*storage = new CHAR[nMaxSize=(contentLength+nMaxSize)]; memcpy(*storage,pszBuffer,read); // Re-assign delete [] pszBuffer; pszBuffer = *storage; } catch( ... ){ return false; } } // Check if body there if(read >= (bodyLen + contentLength)){ ptrHeadEnd[contentLength]=0; return true; } // Expect data (15 seconds ???) if(!waitForEvent(link,15000)) return false; } }
////////////////////////// // Read header & populate text with body ////////////////////////// bool CMimeProtocol::readMimeResponse(int link,CHARPTR headers,int size,CHARPTR content) { CHAR buffer[CBUFF_HUGE+2]; CHARPTR ptrHeadEnd; CHARPTR ptrContLen; int read=0; int bytes; // Reset strcpy(content,""); strcpy(headers,""); // 1st read headers while(true){ // Wait if(!waitForEvent(link,10000)){ strcpy(content,headers); return true; } // Read next lot while((bytes = recvTcp(link,&headers[read],size-read)) <= 0){ switch(OSALASTERROR){ // No data to read - try again case OSAWOULDBLOCK: if(!waitForEvent(link,2000)) return false; continue; // Oh oh default: return false; } return false; } read+=bytes; headers[read]=0; // Check for header & body ptrHeadEnd=strstr(headers,"\r\n\r\n"); // No header yet if(ptrHeadEnd) break; } ptrContLen=strstr(headers,"Content-Length: "); int contentLength; // Terminate *ptrHeadEnd=0; // Header & nobody - copy headers if(!ptrContLen){ // Just keep reading until server closes connection contentLength=128000; ptrHeadEnd += strlen("\r\n\r\n"); strcpy(content,ptrHeadEnd); } else{ // Get content length if(!strparse(ptrContLen,"Content-Length: %1d",&contentLength)) return false; // Skip to start of body ptrHeadEnd += strlen("\r\n\r\n"); strcpy(content,ptrHeadEnd); } // Calculate remaining read = strlen(ptrHeadEnd); while(read < contentLength){ // Read next lot if((bytes = recvTcp(link,buffer,CBUFF_HUGE)) <= 0){ switch(bytes){ // Remote closure case 0: return true; // Error - check default: switch(OSALASTERROR){ // No data to read - try again case OSAWOULDBLOCK: if(!waitForEvent(link,2000)) return false; continue; // Oh oh default: return false; } break; } } buffer[bytes] = 0; read+=bytes; strcat(content,buffer); } // Good to go return true; }