📄 http_client.pc
字号:
/* * GloMoSim is COPYRIGHTED software. Release 2.02 of GloMoSim is available * at no cost to educational users only. * * Commercial use of this software requires a separate license. No cost, * evaluation licenses are available for such purposes; please contact * info@scalable-networks.com * * By obtaining copies of this and any other files that comprise GloMoSim2.02, * you, the Licensee, agree to abide by the following conditions and * understandings with respect to the copyrighted software: * * 1.Permission to use, copy, and modify this software and its documentation * for education and non-commercial research purposes only is hereby granted * to Licensee, provided that the copyright notice, the original author's * names and unit identification, and this permission notice appear on all * such copies, and that no charge be made for such copies. Any entity * desiring permission to use this software for any commercial or * non-educational research purposes should contact: * * Professor Rajive Bagrodia * University of California, Los Angeles * Department of Computer Science * Box 951596 * 3532 Boelter Hall * Los Angeles, CA 90095-1596 * rajive@cs.ucla.edu * * 2.NO REPRESENTATIONS ARE MADE ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY * PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * 3.Neither the software developers, the Parallel Computing Lab, UCLA, or any * affiliate of the UC system shall be liable for any damages suffered by * Licensee from the use of this software. */// Use the latest version of Parsec if this line causes a compiler error./* * $Id: http_client.pc,v 1.4 2001/02/15 03:17:26 mineo Exp $ * * This file contains initialization function, message processing * function, and finalize function used by each http client. * This code is adapted from the work published by Bruce Mah. * B. Mah, "An Empirical Model of HTTP Network Traffic", * Proceedings of INFOCOM '97, Kobe, Japan, April 1997. * http://www.employees.org/~bmah/Papers/Http-Infocom.pdf * * Differences/Modifications to the above model: * 1) 0 length request/response packets are changed to 1-byte packets * 2) The addition of a threshhold parameter that limits the maximum * "think time" between page requests * 3) The use of this maximum threshhold parameter to recover from * disconnections- the http client will re-initiate page requests if * it is waiting for a response from the server, and has not received * an update in {maximum threshhold} time. * * Send questions to Julian Hsu <gandy@cs.ucla.edu> */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include "api.h"#include "structmsg.h"#include "fileio.h"#include "message.h"#include "application.h"#include "app_util.h"#include "http_distribution.h"#include "http_client.h"#include "tcpapps.h"#include "tcp.h"#define noDEBUG/* * NAME: AppLayerHttpClient. * PURPOSE: Models the behaviour of Http Client on receiving the * message encapsulated in msg. * PARAMETERS: nodePtr - pointer to the node which received the message. * msg - message received by the layer * RETURN: none. */void AppLayerHttpClient(GlomoNode *nodePtr, Message *msg){ char buf[GLOMO_MAX_STRING_LENGTH]; GlomoAppHttpClient *clientPtr; ctoa(simclock(), buf); switch(msg->eventType) { case MSG_APP_FromTransOpenResult: { TransportToAppOpenResult *openResult; openResult = (TransportToAppOpenResult *) msg->info; #ifdef DEBUG printf("%s: node %u got OpenResult\n", buf, nodePtr->nodeAddr); #endif assert(openResult->type == TCP_CONN_ACTIVE_OPEN); if (openResult->connectionId < 0) { #ifdef DEBUG printf("%s: node %u connection failed!\n", buf, nodePtr->nodeAddr); #endif nodePtr->appData.numAppTcpFailure ++; } else { GlomoAppHttpClient *clientPtr; long primaryRequestLength; clientPtr = AppHttpClientUpdateHttpClient(nodePtr, openResult); assert(clientPtr != NULL); clientPtr->documentsOnCurrentServer--; clientPtr->stats.pageItems = AppHttpClientDetermineItemCount(clientPtr);#ifdef DEBUG printf(" There are %d items on this page.\n", clientPtr->stats.pageItems);#endif clientPtr->stats.pageItems--; primaryRequestLength = AppHttpClientDeterminePrimaryRequestLength(clientPtr);#ifdef DEBUG printf(" Primary request length = %d\n", primaryRequestLength);#endif AppHttpClientSendPrimaryRequest(nodePtr, clientPtr, primaryRequestLength); #ifdef DEBUG printf("#%u: HTTP Client: TCP Open\n", nodePtr->nodeAddr); #endif } break; } case MSG_APP_FromTransDataSent: { TransportToAppDataSent *dataSent; dataSent = (TransportToAppDataSent *) msg->info; #ifdef DEBUG printf("%s: node %u sent data %ld\n", buf, nodePtr->nodeAddr, dataSent->length); #endif clientPtr = AppHttpClientGetHttpClient(nodePtr, dataSent->connectionId); assert(clientPtr != NULL); clientPtr->numBytesSent += dataSent->length; if ((clientPtr->state == XMIT_PRIMARY_REQUEST) || (clientPtr->state == XMIT_SECONDARY_REQUEST)) { char payload[MAX_APP_DATA_UNIT]; long sendSize; assert (clientPtr->stats.itemRequestBytes > 0); memset(payload, 0, MAX_APP_DATA_UNIT); sendSize = MIN(clientPtr->stats.itemRequestBytes, MAX_APP_DATA_UNIT); clientPtr->stats.itemRequestBytes -= sendSize; if (clientPtr->stats.itemRequestBytes == 0) { if (clientPtr->state == XMIT_PRIMARY_REQUEST) { payload[sendSize-1] = 'p'; clientPtr->state = WAIT_PRIMARY_RESPONSE; AppHttpClientSendWaitReplyTimer(nodePtr, clientPtr, WAIT_PRIMARY_REPLY_TIMER); } else { payload[sendSize-1] = 's'; clientPtr->state = WAIT_SECONDARY_RESPONSE; AppHttpClientSendWaitReplyTimer(nodePtr, clientPtr, WAIT_SECONDARY_REPLY_TIMER); } } AppTcpSendData(nodePtr, TRANSPORT_PROTOCOL_TCP, clientPtr->connectionId, payload, sendSize); } else if ( ( (clientPtr->state == WAIT_PRIMARY_RESPONSE) || (clientPtr->state == WAIT_SECONDARY_RESPONSE) || (clientPtr->state == IDLE)) && (clientPtr->stats.itemRequestBytes == 0)) { // DONE transmitting } else assert(FALSE); break; } case MSG_APP_FromTransDataReceived: { TransportToAppDataReceived *dataRecvd; dataRecvd = (TransportToAppDataReceived *) msg->info; #ifdef DEBUG printf("%s: node %u received data %ld\n", buf, nodePtr->nodeAddr, msg->packetSize); #endif clientPtr = AppHttpClientGetHttpClient(nodePtr, dataRecvd->connectionId); assert(clientPtr != NULL); clientPtr->numBytesRecvd += msg->packetSize; if (msg->packet[msg->packetSize - 1] == 0) { clientPtr->lastReceiveTime = simclock(); } else if (msg->packet[msg->packetSize - 1] == 'd') {#ifdef DEBUG printf("#%ld: HTTP - Received Reply Packet.\n", nodePtr->nodeAddr);#endif clientPtr->lastReceiveTime = simclock(); AppHttpClientProcessReplyPacket(nodePtr, clientPtr); } else assert(FALSE); break; } case MSG_APP_FromTransCloseResult: { TransportToAppCloseResult *closeResult; closeResult = (TransportToAppCloseResult *) msg->info; #ifdef DEBUG printf("%s: node %u got close result\n", buf, nodePtr->nodeAddr); #endif clientPtr = AppHttpClientGetHttpClient(nodePtr, closeResult->connectionId); if(clientPtr == NULL) break; if (clientPtr->sessionIsClosed == FALSE) { clientPtr->sessionIsClosed = TRUE; clientPtr->state = IDLE; } break; } case MSG_APP_TimerExpired: { AppInfo *appList = nodePtr->appData.appPtr; GlomoAppHttpClient *tmpHttpClient = NULL; GlomoAppHttpClient *httpClient = NULL; HttpClientTimer *timer; timer = (HttpClientTimer *) GLOMO_MsgReturnInfo(msg); for (; appList != NULL; appList = appList->appNext) { if (appList->appType == APP_HTTP_CLIENT) { tmpHttpClient = (GlomoAppHttpClient *) appList->appDetail; #ifdef DEBUG printf("HTTP Client: Node %ld comparing uniqueId " "%ld with %ld\n", nodePtr->nodeAddr, tmpHttpClient->uniqueId, timer->clientId); #endif if (tmpHttpClient->uniqueId == timer->clientId) { httpClient = tmpHttpClient; break; } } } if (httpClient == NULL) assert(FALSE); if (timer->timerType == THINK_TIMER) {#ifdef DEBUG printf("#%ld: DONE Thinking....\n",nodePtr->nodeAddr);#endif AppHttpClientProcessDoneThinking(nodePtr, httpClient); } else {#ifdef DEBUG printf("%ld: PROCESS WaitReplyTimer...\n", nodePtr->nodeAddr);#endif AppHttpClientProcessWaitReplyTimer(nodePtr, httpClient); } break; } default: ctoa(simclock(), buf); printf("Time %s: Node %u received message of unknown type" " %ld.\n", buf, nodePtr->nodeAddr, msg->eventType); assert(FALSE); } GLOMO_MsgFree(nodePtr, msg);}/* * NAME: AppHttpClientSendThinkTimer. * PURPOSE: Send a Timeout to itself at the end of the determined * thinking period. * PARAMETERS: nodePtr - pointer to the node which received the message. * clientPtr - pointer to the client's data structure * thinkTime - determined thinking period * RETURN: none. */void AppHttpClientSendThinkTimer(GlomoNode *nodePtr, GlomoAppHttpClient *clientPtr, clocktype thinkTime){ Message *newMsg; HttpClientTimer *timer; newMsg = GLOMO_MsgAlloc(nodePtr, GLOMO_APP_LAYER, APP_HTTP_CLIENT, MSG_APP_TimerExpired); GLOMO_MsgInfoAlloc(nodePtr, newMsg, sizeof(HttpClientTimer)); timer = (HttpClientTimer *) GLOMO_MsgReturnInfo(newMsg); timer->clientId = clientPtr->uniqueId; timer->timerType = THINK_TIMER; GLOMO_MsgSend(nodePtr, newMsg, thinkTime);}/* * NAME: AppHttpClientSendWaitReplyTimer. * PURPOSE: Send a Timeout to itself just in case the server never replies * to a page request. Times out at the maximum think threshhold * parameter. * PARAMETERS: nodePtr - pointer to the node which received the message. * clientPtr - pointer to the client's data structure * timerType - either WAIT_PRIMARY_RESPONSE or * WAIT_SECONDARY_RESPONSE * RETURN: none. */void AppHttpClientSendWaitReplyTimer(GlomoNode *nodePtr, GlomoAppHttpClient *clientPtr, HttpClientTimerType timerType){ Message *newMsg; HttpClientTimer *timer; newMsg = GLOMO_MsgAlloc(nodePtr, GLOMO_APP_LAYER, APP_HTTP_CLIENT, MSG_APP_TimerExpired); GLOMO_MsgInfoAlloc(nodePtr, newMsg, sizeof(HttpClientTimer)); timer = (HttpClientTimer *) GLOMO_MsgReturnInfo(newMsg); timer->clientId = clientPtr->uniqueId; timer->timerType = timerType; GLOMO_MsgSend(nodePtr, newMsg, clientPtr->threshhold);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -