📄 netdiagnostics.c
字号:
ND_Print(pApp, "** DNS Lookup Failed: Error %d\n", nErr);
ReleaseObj((void**)&pApp->m_pISocket);
return;
}
// Cache Start Time
pApp->m_nTotalTime = GETUPTIMEMS();
nErr = ISOCKET_SendTo(pApp->m_pISocket, (byte*)pApp->m_pszMsg, pApp->m_nDataLength, 0,
pApp->m_dnsr.addrs[0], HTONS(IPPORT_ECHO));
if (nErr == AEE_NET_WOULDBLOCK) {
ND_Print(pApp, "** sending...\n");
ISOCKET_Writeable(pApp->m_pISocket, (PFNNOTIFY)Echoer_UDPWrite, pApp);
} else if (nErr == AEE_NET_ERROR) {
ND_Print(pApp, "Send Failed: Error %d\n", ISOCKET_GetLastError(pApp->m_pISocket));
ReleaseObj((void**)&pApp->m_pISocket);
} else {
ND_Print(pApp, "** sending complete...\n");
// Reset Buffer
MEMSET(pApp->m_pszMsg, 0, pApp->m_nDataLength);
Echoer_UDPRead(pApp);
}
}
/*===========================================================================
FUNCTION: Echoer_UDPRead
DESCRIPTION:
Receives UDP data from a socket
PARAMETERS:
pApp [in] - Pointer to the CNetDiagnosticsApp structure. This structure contains
information specific to this applet.
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void Echoer_UDPRead(CNetDiagnosticsApp * pApp)
{
int nRead;
nRead = ISOCKET_RecvFrom(pApp->m_pISocket, (byte *)pApp->m_pszMsg,
pApp->m_nDataLength,0,0,0);
if (nRead == AEE_NET_ERROR) {
ND_Print(pApp, "Receive Failed: Error %d\n", ISOCKET_GetLastError(pApp->m_pISocket));
ReleaseObj((void**)&pApp->m_pISocket);
} else {
if (nRead == AEE_NET_WOULDBLOCK) {
ND_Print(pApp, "** receiving...\n");
ISOCKET_Readable(pApp->m_pISocket, (PFNNOTIFY)Echoer_UDPRead, pApp);
} else {
// Calculate Total Time
pApp->m_nTotalTime = (GETUPTIMEMS() - pApp->m_nTotalTime);
ND_Print(pApp, "** receiving complete...\n");
if (pApp->m_bRS) {
ND_Print(pApp, "%s\n", pApp->m_pszMsg);
}
if (pApp->m_bRT) {
ND_Print(pApp, "Total Time: %d ms", pApp->m_nTotalTime);
}
ReleaseObj((void**)&pApp->m_pISocket);
}
}
}
/*===========================================================================
FUNCTION: WebAction_Start
DESCRIPTION:
Kicks off a web transaction
PARAMETERS:
pwa: wrapper for the web transaction
pszUrl: the URL to go GET/POST
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_Start(WebAction *pwa, char *pszUrl)
{
ISourceUtil *pisu;
CNetDiagnosticsApp * pApp = pwa->pParent;
// look to see if there's POST data, this is totally non-standard, but
// easy to put into tests
pwa->pszPostData = STRCHR(pszUrl, 1);
// if there's post data, construct a stream for IWeb to consume
if ((char *)0 != pwa->pszPostData) {
*pwa->pszPostData = 0;
if (SUCCESS ==
ISHELL_CreateInstance(pApp->a.m_pIShell,AEECLSID_SOURCEUTIL,
(void **)&pisu)) {
ISOURCEUTIL_PeekFromMemory(pisu, pwa->pszPostData + 1,
STRLEN(pwa->pszPostData + 1), 0, 0,
&pwa->pipPostData);
ISOURCEUTIL_Release(pisu);
}
}
// initialize the callback, where I'll be called when the request
// completes
CALLBACK_Init(&pwa->cb, WebAction_GotResp, pwa);
pwa->uStart = GETUPTIMEMS();
// start transaction, pass callbacks for web status, web headers
// the extra WEBOPT_HEADER is used to help test what's sent
// (snoop.sh above shows all the headers)
if ((IPeek *)0 != pwa->pipPostData) {
IWEB_GetResponse(pApp->m_pIWeb,
(pApp->m_pIWeb, &pwa->piWResp, &pwa->cb, pszUrl,
WEBOPT_HANDLERDATA, pwa,
WEBOPT_HEADER, "X-Method: POST\r\n", /* for kicks */
WEBOPT_HEADERHANDLER, WebAction_Header,
WEBOPT_STATUSHANDLER, WebAction_Status,
WEBOPT_METHOD, "POST",
WEBOPT_BODY, pwa->pipPostData,
WEBOPT_CONTENTLENGTH, STRLEN(pwa->pszPostData + 1),
WEBOPT_END));
} else {
IWEB_GetResponse(pApp->m_pIWeb,
(pApp->m_pIWeb, &pwa->piWResp, &pwa->cb, pszUrl,
WEBOPT_HANDLERDATA, pwa,
WEBOPT_HEADER, "X-Method: GET\r\n",
WEBOPT_HEADERHANDLER, WebAction_Header,
WEBOPT_STATUSHANDLER, WebAction_Status,
WEBOPT_END));
}
}
/*===========================================================================
FUNCTION: WebAction_GotResp
DESCRIPTION:
Web transaction callback, fires when the response body is ready to
be read, or when an error has occurred
PARAMETERS:
p: the WebAction
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_GotResp(void *p)
{
WebAction *pwa = (WebAction *)p;
CNetDiagnosticsApp * pApp = pwa->pParent;
WebRespInfo *pwri;
// get information about how the web transaction went
// pwa->piWResp is ***NEVER NULL***, even though the transaction may fail
// for wont of memory
pwri = IWEBRESP_GetInfo(pwa->piWResp);
ND_Print(pApp, "** got response...\n** info code: %d\n", pwri->nCode);
// body may be NULL
if ((ISource *)0 != pwri->pisMessage) {
ISourceUtil *pisu;
// read the body by creating an IGetLine to help parse into lines
// This step is not actually necessary if you don't need line-by-line
// output. In that case, use pisMessage directly.
ISHELL_CreateInstance(pApp->a.m_pIShell,AEECLSID_SOURCEUTIL,
(void **)&pisu);
if ((ISourceUtil *)0 != pisu) {
ISOURCEUTIL_GetLineFromSource(pisu, pwri->pisMessage, 1100,
&pwa->piGetLine);
ISOURCEUTIL_Release(pisu);
}
}
if ((IGetLine *)0 != pwa->piGetLine) {
pwa->uRecvStart = GETUPTIMEMS(); // record that I started reading
// got an IGetLine, go ahead and read it
pwa->nBytes = 0;
WebAction_ReadLines(pwa);
} else {
// ug, tranaction failed or couldn't get an IGetLine, oh well, bail
ND_Print(pApp, "** no response\n");
WebAction_Stop(pwa); // stop cleans up
}
}
/*===========================================================================
FUNCTION: WebAction_Header
DESCRIPTION:
Received header callback for a web transaction. cpszName is NULL in the case
of continuation header line parts.
PARAMETERS:
p: a WebAction (the subscriber)
cpszName: the name of the web header (like "Content-Type")
pglVal: the value of the header, like "text/html"
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_Header(void *p, const char *cpszName, GetLine *pglVal)
{
WebAction *pwa = (WebAction *)p;
CNetDiagnosticsApp * pApp = pwa->pParent;
if (pApp->m_bRS) { // If response is to be displayed
if ((char *)0 != cpszName) {
ND_Print(pApp, "%s:", cpszName);
}
ND_Print(pApp, "%s\n", pglVal->psz);
}
}
/*===========================================================================
FUNCTION: WebAction_Status
DESCRIPTION:
Web status callback for a Web transaction
PARAMETERS:
p: a WebAction (the subscriber)
ws: type of status
pVal: unused as of yet
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_Status(void *p, WebStatus ws, void *pVal)
{
char * pszStatus = 0;
WebAction * pwa = (WebAction *)p;
(void)pVal;
switch (ws) {
case WEBS_CANCELLED:
pszStatus = "** cancelled...\n";
break;
case WEBS_GETHOSTBYNAME:
pszStatus = "** finding host...\n";
break;
case WEBS_CONNECT:
pszStatus = "** connecting...\n";
break;
case WEBS_SENDREQUEST:
pszStatus = "** sending...\n";
break;
case WEBS_READRESPONSE:
pszStatus = "** receiving...\n";
break;
case WEBS_GOTREDIRECT:
pszStatus = "** redirect...\n";
break;
case WEBS_CACHEHIT:
pszStatus = "** cache hit...\n";
break;
}
// show that status!
if ((char *)0 != pszStatus) {
ND_Print(pwa->pParent, "%s", pszStatus);
}
}
/*===========================================================================
FUNCTION: WebAction_Stop
DESCRIPTION:
Halts a web transaction, wrapped/represented by a WebAction
PARAMETERS:
pwa: the WebAction
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_Stop(WebAction *pwa)
{
// this cancels any pending web transaction, or readable on the
// response body. if nothing is pending, this has no effect
CALLBACK_Cancel(&pwa->cb);
// then clean up, if necessary
if ((char *)0 != pwa->pszPostData) {
*pwa->pszPostData = 1; // write delimiter back in, if any
pwa->pszPostData = 0;
}
ReleaseObj((void **)&pwa->pipPostData);
ReleaseObj((void **)&pwa->piGetLine); // let body go
ReleaseObj((void **)&pwa->piWResp); // let response go
}
/*===========================================================================
FUNCTION: WebAction_ReadLines
DESCRIPTION:
consumes the body of a web response, line by line, is called when the
IGetLine that represents the body is readable.
PARAMETERS:
pwa: wrapper for the web transaction
pszUrl: the URL to go GET/POST
DEPENDENCIES:
None
RETURN VALUE:
None
SIDE EFFECTS:
None
===========================================================================*/
static void WebAction_ReadLines(void *p)
{
int rv;
GetLine gl;
WebAction *pwa = (WebAction *)p;
CNetDiagnosticsApp * pApp = pwa->pParent;
// read a line
rv = IGETLINE_GetLine(pwa->piGetLine, &gl, IGETLINE_LF);
if (rv == IGETLINE_WAIT) {
CALLBACK_Init(&pwa->cb, WebAction_ReadLines, pwa);
IGETLINE_Peekable(pwa->piGetLine, &pwa->cb);
return;
}
// process line
pwa->nBytes += gl.nLen + IGETLINE_EOLSize(rv);
if (pApp->m_bRS) {
// show all data
ND_Print(pApp, "%s\n", gl.psz, NULL, TRUE);
} else {
// show one hash mark per line (truncated or otherwise)
ND_Print(pApp, "#");
}
// if stream has not reached EOF or ERROR
if (!IGETLINE_Exhausted(rv)) {
// wait for more data
CALLBACK_Init(&pwa->cb, WebAction_ReadLines, pwa);
IGETLINE_Readable(pwa->piGetLine, &pwa->cb);
return;
}
// no more data
if (rv == IGETLINE_ERROR) {
ND_Print(pApp, "\n** error\n");
} else {
ND_Print(pApp, "\n** end\n");
}
if (pApp->m_bRT) {
uint32 uNow = GETUPTIMEMS();
ND_Print(pApp,
"** %d bytes\n"
"** %dB/s\n"
"** %dms et (recv)\n"
"** %dms et (total)\n",
pwa->nBytes,
pwa->nBytes * 1000 / MAX(1,uNow - pwa->uRecvStart),
uNow - pwa->uRecvStart,
uNow - pwa->uStart);
}
// am done, _Stop cleans up
WebAction_Stop(pwa);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -