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

📄 c-netapi3.html

📁 vxworks相关论文
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<p class="listspace"><ul class="Bullet" type="disc"><li><a name="89692"> </a>Do not change data if any other zbuf segment is sharing it.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="89693"> </a>As with any other direct memory access, it is up to your own code to restrict itself to meaningful data: remember that the next segment in a zbuf is usually not contiguous.  Use <b class="routine"><i class="routine">zbufSegLength</i></b><b>(&nbsp;)</b> as a limit, and <b class="routine"><i class="routine">zbufSegNext</i></b><b>(&nbsp;)</b> when you exceed that limit.</li></ul></p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="89697">Example: Manipulating Zbuf Structure</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89698"> </a>The following interaction illustrates the use of some of the previously described <b class="library">zbufLib</b> routines, and their effect on zbuf segments and data sharing.  To keep the example manageable, the zbuf data used is artificially small, and the execution environment is the Tornado shell (for details on this shell, see the <i class="title">Tornado User's Guide: Shell</i>).</p><dd><p class="Body"><a name="89699"> </a>To begin with, we create a zbuf, and use its ID <b class="symbol_lc">zId</b> to verify that a newly created zbuf contains no data; <b class="routine"><i class="routine">zbufLength</i></b><b>(&nbsp;)</b> returns a result of 0.</p><dl class="margin"><dd><pre class="Code2"><b><a name="89700"></b><tt class="output">-&gt; </tt><b>zId = zbufCreate() </b><tt class="output">new symbol "zId" added to symbol table. zId = 0x3b58e8: value = 3886816 = 0x3b4ee0 -&gt; </tt><b>zbufLength (zId) </b><tt class="output">value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89701"> </a>Next, we create a data buffer <b class="symbol_lc">buf1</b>, insert it into zbuf <b class="symbol_lc">zId</b>, and verify that <b class="routine"><i class="routine">zbufLength</i></b><b>(&nbsp;)</b> now reports a positive length.  To keep the example simple, <b class="symbol_lc">buf1</b> is a literal string, and therefore we do not supply a free-routine callback argument to <b class="routine"><i class="routine">zbufInsertBuf</i></b><b>(&nbsp;)</b>.</p><dl class="margin"><dd><pre class="Code2"><b><a name="89702"></b><tt class="output">-&gt; </tt><b>buf1 = "I cannot repeat enough!" </b><tt class="output">new symbol "buf1" added to symbol table. buf1 = 0x3b5898: value = 3889320 = 0x3b58a8 = buf1 + 0x10 -&gt; </tt><b>zbufInsertBuf (zId, 0, 0, buf1, strlen(buf1), 0, 0) </b><tt class="output">value = 3850240 = 0x3ac000 -&gt; </tt><b>zbufLength (zId) </b><tt class="output">value = 23 = 0x17</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89703"> </a>To examine the effect of other zbuf operations, it is useful to have a zbuf-display routine.  The remainder of this example uses a routine called <b class="routine"><i class="routine">zbufDisplay</i></b><b>(&nbsp;)</b> for that purpose; for the complete source code, see <a href="c-netapi3.html#89723">Example&nbsp;7-4</a>.</p><dd><p class="Body"><a name="89707"> </a>For each zbuf segment, <b class="routine"><i class="routine">zbufDisplay</i></b><b>(&nbsp;)</b> shows the segment ID, the start-of-data address, the offset from that address, the length of the segment, and the data in the segment as a character string.  The following display of <b class="symbol_lc">zId</b> illustrates that the underlying data in its only segment is still at the <b class="symbol_lc">buf1</b> address (0x3b58a8), because <b class="routine"><i class="routine">zbufInsertBuf</i></b><b>(&nbsp;)</b> incorporates its buffer argument into the zbuf without copying data.</p><dl class="margin"><dd><pre class="Code2"><b><a name="89708"></b><tt class="output">-&gt; </tt><b>ld &lt;/usr/jane/zbuf-examples/zbufDisplay.o </b><tt class="output">value = 3890416 = 0x3b5cf0 = zbufDisplay.o_bss + 0x8 -&gt; </tt><b>zbufDisplay zId </b><tt class="output">segID 0x3ac000 at 0x3b58a8 + 0x0 (23 bytes): I cannot repeat enough! value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89709"> </a>When we copy the zbuf, the copy has its own IDs, but still uses the same data address:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89710"></b><tt class="output">-&gt; </tt><b>zId2 = zbufDup (zId,0,0,23) </b><tt class="output">new symbol "zId2" added to symbol table. zId2 = 0x3b5ff0: value = 3886824 = 0x3b4ee8 -&gt; </tt><b>zbufDisplay zId2 </b><tt class="output">segID 0x3abf80 at 0x3b58a8 + 0x0 (23 bytes): I cannot repeat enough! value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89711"> </a>If we insert a second buffer into the middle of the existing data in<b class="symbol_lc"> zId</b>, there is still no data copying.  Inserting the new buffer gives us a zbuf made up of three segments--but notice that the address of the first segment is still the start of <b class="symbol_lc">buf1</b>, and the third segment points into the middle of <b class="symbol_lc">buf1</b>:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89712"></b><tt class="output">-&gt; </tt><b>buf2 = " this" </b><tt class="output">new symbol "buf2" added to symbol table. buf2 = 0x3b5fb0: value = 3891136 = 0x3b5fc0 = buf2 + 0x10 -&gt; </tt><b>zbufInsertBuf (zId, 0, 15, buf2, strlen(buf2), 0, 0) </b><tt class="output">value = 3849984 = 0x3abf00 -&gt; </tt><b>zbufDisplay zId </b><tt class="output">segID 0x3ac000 at 0x3b58a8 + 0x0 (15 bytes): I cannot repeat segID 0x3abf00 at 0x3b5fc0 + 0x0 ( 5 bytes):  this segID 0x3abe80 at 0x3b58b7 + 0x0 ( 8 bytes):  enough! value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89713"> </a>Because the underlying buffer is not modified, both <b class="symbol_lc">buf1</b> and the duplicate zbuf <b class="symbol_lc">zId2</b> still contain the original string, rather than the modified one now in <b class="symbol_lc">zId</b>:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89714"></b><tt class="output">-&gt; </tt><b>printf ("%s\n", buf1) </b><tt class="output">I cannot repeat enough! value = 24 = 0x18 -&gt; </tt><b>zbufDisplay zId2 </b><tt class="output">segID 0x3abf80 at 0x3b58a8 + 0x0 (23 bytes): I cannot repeat enough! value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89715"> </a>The <b class="routine"><i class="routine">zbufDup</i></b><b>(&nbsp;)</b> routine can also select part of a zbuf without copying, for instance to incorporate some of the same data into another zbuf--or even into the same zbuf, as in the following example:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89716"></b><tt class="output">-&gt; </tt><b>zTmp = zbufDup (zId, 0, 15, 5) </b><tt class="output">new symbol "zTmp" added to symbol table. zTmp = 0x3b5f70: value = 3886832 = 0x3b4ef0</tt><b></a></b><dd> <b><a name="89717"></b><tt class="output">-&gt; </tt><b>zbufInsert (zId, 0, 15, zTmp) </b><tt class="output">value = 3849728 = 0x3abe00 -&gt; </tt><b>zbufDisplay zId </b><tt class="output">segID 0x3ac000 at 0x3b58a8 + 0x0 (15 bytes): I cannot repeat segID 0x3abe00 at 0x3b5fc0 + 0x0 ( 5 bytes):  this segID 0x3abf00 at 0x3b5fc0 + 0x0 ( 5 bytes):  this segID 0x3abe80 at 0x3b58b7 + 0x0 ( 8 bytes):  enough! value = 0 = 0x0</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89718"> </a>After <b class="routine"><i class="routine">zbufInsert</i></b><b>(&nbsp;)</b> combines two zbufs, the second zbuf ID (<b class="symbol_lc">zTmp</b> in this example) is automatically deleted. Thus, <b class="symbol_lc">zTmp</b> is no longer a valid zbuf ID--for example, <b class="routine"><i class="routine">zbufLength</i></b><b>(&nbsp;)</b> returns <b class="symbol_UC">ERROR</b>:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89719"></b><tt class="output">-&gt; </tt><b>zbufLength (zTmp) </b><tt class="output">value = -1 = 0xffffffff = zId2 + 0xffc4a00f</tt><b></a></b></pre></dl><dd><p class="Body"><a name="89720"> </a>However, you must still delete the remaining two zbuf IDs explicitly when they are no longer needed.  This releases all associated zbuf-structure storage.  In a real application, with free-routine callbacks filled in, it also calls the specified free routine on the data buffers, as follows:</p><dl class="margin"><dd><pre class="Code2"><b><a name="89721"></b><tt class="output">-&gt; </tt><b>zbufDelete (zId) </b><tt class="output">value = 0 = 0x0 -&gt; </tt><b>zbufDelete (zId2) </b><tt class="output">value = 0 = 0x0</tt><b></a></b></pre></dl></dl></dl><h4 class="EntityTitle"><a name="89723"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 7-4:&nbsp;&nbsp;Zbuf Display Routine</font></a></h4><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89725"> </a>The following is the complete source code for the <b class="routine"><i class="routine">zbufDisplay</i></b><b>(&nbsp;)</b> utility used in the preceding example:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="89726">/* zbufDisplay.c - zbuf example display routine */  /* includes */  #include "vxWorks.h" #include "zbufLib.h" #include "ioLib.h" #include "stdio.h"</a></b><dd> <b><a name="89732">/******************************************************************** * * zbufDisplay - display contents of a zbuf * * RETURNS: OK, or ERROR if the specified data could not be displayed. */</a></b><dd> <b><a name="89734">STATUS zbufDisplay     (     ZBUF_ID     zbufId,         /* zbuf to display */     ZBUF_SEG    zbufSeg,        /* zbuf segment base for &lt;offset&gt; */     int         offset,         /* relative byte offset */     int         len,            /* number of bytes to display */     BOOL        silent          /* do not print out debug info */     )     {     int         lenData;     char *      pData;</a></b><dd> <b><a name="89736">    /* find the most-local byte location */</a></b><dd> <b><a name="89738">    if ((zbufSeg = zbufSegFind (zbufId, zbufSeg, &amp;offset)) == NULL)         return (ERROR);</a></b><dd> <b><a name="89740">    if (len &lt;= 0)         len = ZBUF_END;</a></b><dd> <b><a name="89742">    while ((len != 0) &amp;&amp; (zbufSeg != NULL))         {         /* find location and data length of zbuf segment */</a></b><dd> <b><a name="89744">        pData = zbufSegData (zbufId, zbufSeg) + offset;         lenData = zbufSegLength (zbufId, zbufSeg) - offset;         lenData = min (len, lenData);     /* print all of seg ? */</a></b><dd> <b><a name="89746">        if (!silent)             printf ("segID 0x%x at 0x%x + 0x%x (%2d bytes): ",                 (int) zbufSeg, (int) pData, offset, lenData);         write (STD_OUT, pData, lenData);     /* display data */         if (!silent)             printf ("\n");</a></b><dd> <b><a name="89748">        zbufSeg = zbufSegNext (zbufId, zbufSeg); /* update segment */         len -= lenData;                      /* update length */         offset = 0;                          /* no more offset */         }</a></b><dd> <b><a name="89750">    return (OK);     }</a></b></pre></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H4"><i><a name="89752">Limitations of the Zbuf Implementation</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89754"> </a>The following zbuf limitations are due to the current implementation; they are not inherent to the data abstraction.  They are described because they can have an impact on application performance.</p></dl><dl class="margin"><p class="listspace"><ul class="Bullet" type="disc"><li><a name="89755"> </a>With the current implementation, references to data in zbuf segments before a particular location (whether with <b class="routine"><i class="routine">zbufSegPrev</i></b><b>(&nbsp;)</b>, or with a negative offset in a byte location) are significantly slower than references to data after a particular location.</li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="89756"> </a>The data in small zbuf segments (less than 512 bytes) is sometimes copied, rather than having references propagated to it.</li></ul></p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="89759">7.3.3  &nbsp;&nbsp;Zbuf Socket Calls</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="89764"> </a>The zbuf socket calls listed in <a href="c-netapi3.html#89768">Table&nbsp;7-8</a> are named to emphasize parallels with the standard BSD socket calls: thus, <b class="routine"><i class="routine">zbufSockSend</i></b><b>(&nbsp;)</b> is the zbuf version of <b class="routine"><i class="routine">send</i></b><b>(&nbsp;)</b>, and <b class="routine"><i class="routine">zbufSockRecvfrom</i></b><b>(&nbsp;)</b> is the zbuf version of <b class="routine"><i class="routine">recvfrom</i></b><b>(&nbsp;)</b>.  The arguments also correspond directly to those of the standard socket calls.<b> </b><p class="table"><h4 class="EntityTitle"><a name="89768"><font face="Helvetica, sans-serif" size="-1" class="sans">Table 7-8:&nbsp;&nbsp;Zbuf Socket Library Routines</font></a></h4><table border="0" cellpadding="0" cellspacing="0"><tr><td colspan="20"><hr class="tablerule"></td></tr><tr valign="middle"><th rowspan="1" colspan="1"><div class="CellHeading"><b><a name="89772"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Call</font></b></div></th><td width="10">&nbsp;</td><th rowspan="1" colspan="1"><div class="CellHeading"><b><a name="89774"> </a><font face="Helvetica, sans-serif" size="-1" class="sans">Description</font></b></div></th><td width="10">&nbsp;</td></tr><tr><td colspan="20"><hr class="tablerule2"></td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89777"> </a><b class="routine"><i class="routine">zbufSockLibInit</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89779"> </a>Initialize socket libraries (called automatically if the configuration has zbuf sockets enabled.  The relevant configuration macro is <b class="symbol_UC">INCLUDE_SOCK_ZBUF</b>).</div></td><td width="10">&nbsp;</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89782"> </a><b class="routine"><i class="routine">zbufSockSend</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89784"> </a>Send zbuf data to a TCP socket.</div></td><td width="10">&nbsp;</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89787"> </a><b class="routine"><i class="routine">zbufSockSendto</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89789"> </a>Send a zbuf message to a UDP socket.</div></td><td width="10">&nbsp;</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89792"> </a><b class="routine"><i class="routine">zbufSockBufSend</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89794"> </a>Create a zbuf and send it as TCP socket data.</div></td><td width="10">&nbsp;</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="89797"> </a><b class="routine"><i class="routine">zbufSockBufSendto</i></b><b>(&nbsp;)</b></div></td><td width="10">&nbsp;</td><td colspan=1 rowspan=1><div class="CellBody"><a name="89799"> </a>Create a zbuf and send it as a UDP socket message.</div></td><td width="10">&nbsp;</td>

⌨️ 快捷键说明

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