⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-netapi3.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 4 页
字号:
</tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89802"> </a><b class="routine"><i class="routine">zbufSockRecv</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89804"> </a>Receive data in a zbuf from a TCP socket.</div></td><td width="10">&nbsp;</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89807"> </a><b class="routine"><i class="routine">zbufSockRecvfrom</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89809"> </a>Receive a message in a zbuf from a UDP socket.</div></td><td width="10">&nbsp;</td></tr><tr><td colspan="20"><hr class="tablerule"></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p></p><dd><p class="Body"><a name="89810"> </a>For a detailed description of each routine, see the corresponding reference entry.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="89811">Standard Socket Calls and Zbuf Socket Calls</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89812"> </a>The zbuf socket calls are particularly useful when large data transfer is a significant part of your socket application.  For example, many socket applications contain sections of code like the following fragment:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89813">pBuffer = malloc (BUFLEN); while ((readLen = read (fdDevice, pBuffer, BUFLEN))  &gt; 0)     write (fdSock, pBuffer, readLen);</a></b></pre></dl><dd><p class="Body"><a name="89815"> </a>You can eliminate the overhead of copying from the application buffer <b class="symbol_lc">pBuffer</b> into the internal socket buffers by changing the code to use zbuf socket calls.  For example, the following fragment is a zbuf version of the preceding loop:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89816">pBuffer = malloc (BUFLEN * BUFNUM);           /* allocate memory */ for (ix = 0; ix &lt; (BUFNUM - 1); ix++, pBuffer += BUFLEN)     appBufRetn (pBuffer);                    /* fill list of free bufs */  while ((readLen = read (fdDevice, pBuffer, BUFLEN)) &gt; 0)     {     zId = zbufCreate ();                     /* insert into new zbuf */     zbufInsertBuf (zId, NULL, 0, pBuffer, readLen, appBufRetn, 0);     zbufSockSend (fdSock, zId, readLen, 0);   /* send zbuf */     pBuffer = appBufGet (WAIT_FOREVER);       /* get a fresh buffer */     }</a></b></pre></dl><dd><p class="Body"><a name="89827"> </a>The <b class="routine"><i class="routine">appBufGet</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">appBufRetn</i></b><b>(&nbsp;)</b> references in the preceding code fragment stand for application-specific buffer management routines, analogous to <b class="routine"><i class="routine">malloc</i></b><b>(&nbsp;)</b> and <b class="routine"><i class="routine">free</i></b><b>(&nbsp;)</b>.  In many applications, these routines do nothing more than manipulate a linked list of free fixed-length buffers.</p></dl></dl><h4 class="EntityTitle"><a name="89829"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 7-5:&nbsp;&nbsp;The TCP Example Server Using Zbufs</font></a></h4><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89831"> </a>For a small but complete example that illustrates the mechanics of using the zbuf socket library, consider the conversion of the client-server example in <a href="c-netapi2.html#88737">Example&nbsp;7-1</a> to use zbuf socket calls. </p><dd><p class="Body"><a name="89835"> </a>No conversion is needed for the client side of the example; the client operates the same regardless of whether or not the server uses zbufs.  The next example illustrates the following changes to convert the server side to use zbufs:</p></dl><dl class="margin"><p class="listspace"><ul class="Dash" type="circle"><li><a name="89836"> </a>Instead of including the header file <b class="file">sockLib.h</b>, include <b class="file">zbufSockLib.h</b>.</li></ul></p><p class="listspace"><ul class="Dash" type="circle"><li><a name="89837"> </a>The data processing component must be capable of dealing with potentially non-contiguous data in successive zbuf segments.  In the TCP example, this component displays a message using <b class="routine"><i class="routine">printf</i></b><b>(&nbsp;)</b>; we can use the <b class="routine"><i class="routine">zbufDisplay</i></b><b>(&nbsp;)</b> routine from <a href="c-netapi3.html#89723">Example&nbsp;7-4</a> instead.</li></ul></p><p class="listspace"><ul class="Dash" type="circle"><li><a name="89841"> </a>The original TCP example exploits <b class="routine"><i class="routine">fioRead</i></b><b>(&nbsp;)</b> to collect the complete message, rather than calling <b class="routine"><i class="routine">recv</i></b><b>(&nbsp;)</b> directly.  To achieve the same end while avoiding data copying by using zbufs, the following example defines a <b class="routine"><i class="routine">zbufFioSockRecv</i></b><b>(&nbsp;)</b> subroutine to call <b class="routine"><i class="routine">zbufSockRecv</i></b><b>(&nbsp;)</b> repeatedly until the complete message is received.</li></ul></p><p class="listspace"><ul class="Dash" type="circle"><li><a name="89842"> </a>A new version of the worker routine <b class="routine"><i class="routine">tcpServerWorkTask</i></b><b>(&nbsp;)</b> must tie together these separate modifications, and must explicitly extract the <b class="symbol_lc">reply</b> and <b class="symbol_lc">msgLen</b> fields from the client's transmission to do so.  When using zbufs, these fields cannot be extracted by reference to the C structure in <b class="file">tcpExample.h</b> because of the possibility that the data is not contiguous.</li></ul></p></dl><dl class="margin"><dd><p class="Body"><a name="89843"> </a>The following example shows the auxiliary <b class="routine"><i class="routine">zbufFioSockRecv</i></b><b>(&nbsp;)</b> routine and the zbuf version of <b class="routine"><i class="routine">tcpServerWorkTask</i></b><b>(&nbsp;)</b>.  To run this code:</p></dl><dl class="margin"><p><ol class="List"><li value="1."><a name="89847"> </a>Start with <b class="file">tcpServer.c</b> as defined in <a href="c-netapi2.html#88737">Example&nbsp;7-1</a>.</li></ol></p><p><ol class="List"><li value="2."><a name="89848"> </a>Include the header file <b class="file">zbufSockLib.h</b>.</li></ol></p><p><ol class="List"><li value="3."><a name="89852"> </a>Insert the <b class="routine"><i class="routine">zbufDisplay</i></b><b>(&nbsp;)</b> routine from <a href="c-netapi3.html#89723">Example&nbsp;7-4</a>.</li></ol></p><p><ol class="List"><li value="4."><a name="89853"> </a>Replace the <b class="routine"><i class="routine">tcpServerWorkTask</i></b><b>(&nbsp;)</b> definition with the following two routines:</li></ol></p></dl><dl class="margin"><dd><pre class="Code"><b><a name="89854">/************************************************************************ * * zbufFioSockRecv - receive &lt;len&gt; bytes from a socket into a zbuf * * This routine receives a specified amount of data from a socket into a * zbuf, by repeatedly calling zbufSockRecv() until &lt;len&gt; bytes * are read. * * RETURNS: * The ID of the zbuf containing &lt;len&gt; bytes of data, * or NULL if there is an error during the zbufSockRecv() operation. * * SEE ALSO: zbufSockRecv() */</a></b><dd> <b><a name="92809">ZBUF_ID zbufFioSockRecv     (     int         fd,             /* file descriptor of file to read */     int         len             /* maximum number of bytes to read */     )     {     BOOL        first = TRUE;           /* first time thru ? */     ZBUF_ID     zRecvTotal = NULL;      /* zbuf to return */     ZBUF_ID     zRecv;                  /* zbuf read from sock */     int         nbytes;                 /* number of recv bytes */</a></b><dd> <b><a name="92811">    for (; len &gt; 0; len -= nbytes)         {         nbytes = len;                   /* set number of bytes wanted */</a></b><dd> <b><a name="89860">        /* read a zbuf from the socket */</a></b><dd> <b><a name="89862">        if (((zRecv = zbufSockRecv (fd, 0, &amp;nbytes)) == NULL) ||             (nbytes &lt;= 0))             {             if (zRecvTotal != NULL)                 zbufDelete (zRecvTotal);             return (NULL);             }</a></b><dd> <b><a name="89864">        /* append recv'ed zbuf onto end of zRecvTotal */</a></b><dd> <b><a name="89865">        if (first)             zRecvTotal = zRecv;         /* cannot append to empty zbuf */         else if (zbufInsert (zRecvTotal, NULL, ZBUF_END, zRecv) == NULL)             {             zbufDelete (zRecv);             zbufDelete (zRecvTotal);             return (NULL);             }</a></b><dd> <b><a name="89866">        first = FALSE;                  /* can append now... */         }</a></b><dd> <b><a name="89867">    return (zRecvTotal);     }</a></b><dd> <b><a name="89869">/************************************************************************ * * tcpServerWorkTask - process client requests * * This routine reads from the server's socket, and processes client * requests.  If the client requests a reply message, this routine * sends a reply to the client. * * RETURNS: N/A. */</a></b><dd> <b><a name="89871">VOID tcpServerWorkTask     (     int                 sFd,            /* server's socket fd */     char *              address,        /* client's socket address */     u_short             port            /* client's socket port */     )     {     static char         replyMsg[] = "Server received your message";     ZBUF_ID             zReplyOrig;     /* original reply msg */     ZBUF_ID             zReplyDup;      /* duplicate reply msg */     ZBUF_ID             zRequest;       /* request msg from client */     int                 msgLen;         /* request msg length */     int                 reply;          /* reply requested ? */</a></b><dd> <b><a name="89873">    /* create original reply message zbuf */</a></b><dd> <b><a name="89874">    if ((zReplyOrig = zbufCreate ()) == NULL)         {         perror ("zbuf create");         free (address);                 /* free malloc from inet_ntoa() */         return;         }</a></b><dd> <b><a name="89876">    /* insert reply message into zbuf */</a></b><dd> <b><a name="89877">    if (zbufInsertBuf (zReplyOrig, NULL, 0, replyMsg,          sizeof (replyMsg), NULL, 0) == NULL)         {         perror ("zbuf insert");         zbufDelete (zReplyOrig);         free (address);                 /* free malloc from inet_ntoa() */         return;         }</a></b><dd> <b><a name="89879">    /* read client request, display message */</a></b><dd> <b><a name="89880">    while ((zRequest = zbufFioSockRecv (sFd, sizeof(struct request))) != NULL)         {         /* extract reply field into &lt;reply&gt; */</a></b><dd> <b><a name="89882">        (void) zbufExtractCopy (zRequest, NULL, 0,             (char *) &amp;reply, sizeof (reply));         (void) zbufCut (zRequest, NULL, 0, sizeof (reply));</a></b><dd> <b><a name="89884">        /* extract msgLen field into &lt;msgLen&gt; */</a></b><dd> <b><a name="89886">        (void) zbufExtractCopy (zRequest, NULL, 0,             (char *) &amp;msgLen, sizeof (msgLen));         (void) zbufCut (zRequest, NULL, 0, sizeof (msgLen));</a></b><dd> <b><a name="89888">        /* duplicate reply message zbuf, preserving original */</a></b><dd> <b><a name="89890">        if ((zReplyDup = zbufDup (zReplyOrig, NULL, 0, ZBUF_END)) == NULL)             {             perror ("zbuf duplicate");             zbufDelete (zRequest);             break;             }</a></b><dd> <b><a name="89892">        printf ("MESSAGE FROM CLIENT (Internet Address %s, port %d):\n",              address, port);                                    /* display request message zbuf */</a></b><dd> <b><a name="89894">        (void) zbufDisplay (zRequest, NULL, 0, msgLen, TRUE);         printf ("\n");         if (reply)              {             if (zbufSockSend (sFd, zReplyDup, sizeof (replyMsg), 0) &lt; 0)                 perror ("zbufSockSend");             }</a></b><dd> <b><a name="89896">        /* finished with request message zbuf */</a></b><dd> <b><a name="89898">        zbufDelete (zRequest);         }</a></b><dd> <b><a name="89900">    free (address);                     /* free malloc from inet_ntoa() */     zbufDelete (zReplyOrig);     close (sFd);     }</a></b></pre></dl></dl><dl class="margin"><dd><p class="table" callout><table border="0" cellpadding="0" cellspacing="0"><tr valign="top"><td valign="top" width="40"><br><img border="0" alt="*" src="icons/caution.gif"></td><td><hr><div class="CalloutCell"><a name="93513"><b class="symbol_UC"><font face="Helvetica, sans-serif" size="-1" class="sans">CAUTION:  </font></b></a>In the interests of brevity, the <b class="symbol_UC">STATUS</b> return values for several zbuf socket calls are discarded with casts to <b class="keyword">void</b>.  In a real application, check these return values for possible errors. </div></td></tr><tr valign="top"><td></td><td><hr></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p callout></dl><a name="foot"><hr></a><p class="navbar" align="right"><a href="index.html"><img border="0" alt="[Contents]" src="icons/contents.gif"></a><a href="c-netapi.html"><img border="0" alt="[Index]" src="icons/index.gif"></a><a href="c-netapi.html"><img border="0" alt="[Top]" src="icons/top.gif"></a><a href="c-netapi2.html"><img border="0" alt="[Prev]" src="icons/prev.gif"></a><a href="c-dns.html"><img border="0" alt="[Next]" src="icons/next.gif"></a></p></body></html><!---by WRS Documentation (), Wind River Systems, Inc.    conversion tool:  Quadralay WebWorks Publisher 4.0.11    template:         CSS Template, Jan 1998 - Jefro --->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -