📄 streams.doc7.html
字号:
</td></tr><tr valign="top"><td colspan=1 rowspan=1><div class="CellBody"><a name="86563" class="autotag"> </a><b class="routine"><i class="routine">t_unbind</i></b><b>( )</b></div></td><td colspan=1 rowspan=1><div class="CellBody"><a name="86565" class="autotag"> </a>Disable a transport endpoint. </div></td></tr><tr valign="top"><td colspan=1 rowspan=1></td><td colspan=1 rowspan=1></td></tr><tr><td colspan="20"><hr class="tablerule"></td></tr><tr valign="middle"><td colspan="20"></td></tr></table></p></p></dd></dl></dd></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="75926" class="autotag">3.1.7 Run-time Configuration of XTI/TLI </a></i></h4></font><dl class="margin"><dd><dl class="margin"><dd><p class="Body"><a name="75927" class="autotag"> </a>You can configure your application during run-time to use either XTI or TLI by choosing <b class="routine"><i class="routine">t_open</i></b><b>( )</b> or <b class="routine"><i class="routine">tli_open</i></b><b>( )</b>, respectively. Calls for connection establishment, event handling, data transfer, and connection release are the same in both XTI and TLI. For additional information on XTI/TLI, consult the XTI/TLI references listed in <a href="x-streamsBiblio.doc.html#757841"><i class="title">Appendix A. WindNet STREAMS Reference List</i></a>. </p><p class="Body"><a name="75928" class="autotag"> </a>To configure XTI semantics into an application at run-time, use <b class="routine"><i class="routine">t_open</i></b><b>( )</b>, as shown in the following code fragment. The <b class="file">/dev/tcp </b>in the example specifies a TPI-compliant transport provider. </p><dl class="margin"><dd><pre class="Code2"><a name="75929" class="autotag">{</a><a name="75930" class="autotag">...</a><a name="75931" class="autotag">t_open("/dev/tcp", O_RDWR, &info);</a><a name="75932" class="autotag">...</a><a name="80168" class="autotag">} </a></pre></dd></dl><p class="Body"><a name="80204" class="autotag"> </a>Applications that require TLI semantics must make a <b class="routine"><i class="routine">tli_open</i></b><b>( )</b> call instead. To configure TLI semantics, use the following code fragment. The <b class="file">/dev/xns</b> in the example also specifies a TPI-compliant transport provider. </p><dl class="margin"><dd><pre class="Code2"><a name="80205" class="autotag">{</a><a name="80206" class="autotag">...</a><a name="80207" class="autotag">tli_open("/dev/xns", O_RDWR, &info);</a><a name="80208" class="autotag">...</a><a name="80209" class="autotag">} </a></pre></dd></dl></dd></dl></dd></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="80170" class="autotag">3.1.8 Examining the Relationship Between XTI and TLI</a></i></h4></font><dl class="margin"><dd><dl class="margin"><dd><p class="Body"><a name="80171" class="autotag"> </a>XTI is a refinement of TLI, the older of the two interfaces. The following features are XTI extensions of TLI:</p></dd></dl><dl class="margin"><dd><p class="listspace"><ul class="Bullet" type="disc"><li><a name="89958" class="autotag"> </a>Additional features have been introduced to <b class="routine"><i class="routine">t_snd</i></b><b>( )</b>, <b class="routine"><i class="routine">t_rcv</i></b><b>( )</b>, <b class="routine"><i class="routine">t_sndrel</i></b><b>( )</b>, and <b class="routine"><i class="routine">t_rcvrel</i></b><b>( )</b> to allow fuller use of transport providers and to cater to service and protocol problems. For example, <b class="routine"><i class="routine">t_snd</i></b><b>( )</b>, <b class="routine"><i class="routine">t_rcv</i></b><b>( )</b>, and <b class="routine"><i class="routine">t_sndrel</i></b><b>( )</b> called out of state in TLI return -1 and do not set the TLI <font face="Palatino, serif"><i class="textVariable">errno</i></font> variable, <b class="keyword">t_errno</b>; whereas, XTI checks for the state, returns <b>ERROR</b>, and sets <b class="keyword">t_errno</b> to <b>TOUTSTATE</b> if the state is not data-transfer. </li></ul></p><p class="listspace"><ul class="Bullet" type="disc"><li><a name="79006" class="autotag"> </a>XTI has modified the packing of the <b>t_opthdr</b> structure as follows:</li></ul></p><dl class="margin"><dd><pre class="Code2"><a name="75940" class="autotag">struct t_opthdr </a><a name="89972" class="autotag"> {</a><a name="75941" class="autotag"> unsigned long len;</a><a name="75942" class="autotag"> unsigned long level;</a><a name="75943" class="autotag"> unsigned long name; </a><a name="75944" class="autotag"> unsigned long status;</a><a name="75945" class="autotag"> };</a></pre><div class="Indent"><a name="75946" class="autotag"> </a>Whereas, in TLI the <b>t_opthdr</b> structure is as follows:</div><br><pre class="Code2"><a name="75947" class="autotag">struct t_opthdr </a><a name="89973" class="autotag"> {</a><a name="75948" class="autotag"> long level;</a><a name="75949" class="autotag"> long name;</a><a name="75950" class="autotag"> long len;</a><a name="75951" class="autotag"> };</a></pre></dd></dl></dd></dl></dd></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="75956" class="autotag">3.1.9 Differences Between the WindNet STREAMS and UNIX XTI/TLI Libraries </a></i></h4></font><dl class="margin"><dd><dl class="margin"><dd><p class="Body"><a name="77146" class="autotag"> </a>The WindNet STREAMS XTI/TLI library is source-compatible with the UNIX XTI/TLI library; however the library differs from its UNIX counterpart in the following way: WindNet STREAMS provides the routine <b class="routine"><i class="routine">tliUserInit</i></b><b>( )</b> to convert the global variable <b class="keyword">t_errno</b> into a task variable. It is mandatory to do this in order to preserve the value of <b class="keyword">t_errno</b> on a task-by-task basis. Without calling <b class="routine"><i class="routine">tliUserInit</i></b><b>( )</b>, you cannot be certain of the reason for the failure of an XTI/TLI service; therefore invoke the routine before any XTI/TLI services are used. </p><p class="Body"><a name="77147" class="autotag"> </a>The following code fragment demonstrates the use of <b class="routine"><i class="routine">tliUserInit</i></b><b>( )</b>:</p><dl class="margin"><dd><pre class="Code2"><a name="77148" class="autotag">{</a><a name="75960" class="autotag">extern int t_errno;</a><a name="75961" class="autotag">tliUserInit();</a><a name="75962" class="autotag">...</a><a name="75964" class="autotag">t_open(...);</a><a name="90452" class="autotag">...</a><a name="75965" class="autotag">}</a></pre></dd></dl></dd></dl></dd></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="75967" class="autotag">3.1.10 Read/Write Interface</a></i></h4></font><dl class="margin"><dd><dl class="margin"><dd><p class="Body"><a name="75968" class="autotag"> </a>The XTI/TLI interface does not directly support a read/write interface to the transport provider; however, the WindNet STREAMS XTI/TLI library does by providing a STREAMS module called <b>tirdwr</b>. Any application requiring the read/write interface pushes the <b>tirdwr</b> module onto the stream associated with the transport endpoint where the connection was established. Use <b>tirdwr</b> as follows:</p><dl class="margin"><dd><pre class="Code2"><a name="75969" class="autotag">{</a><a name="75970" class="autotag">...</a><a name="75971" class="autotag">ioctl(fd, I_PUSH, "tirdwr");</a><a name="75972" class="autotag">read(fd,...);</a><a name="75973" class="autotag">write(fd,...);</a><a name="75974" class="autotag">...</a><a name="75975" class="autotag">}</a></pre></dd></dl></dd></dl></dd></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="79117" class="autotag">3.1.11 XTI Client-Server Applications</a></i></h4></font><dl class="margin"><dd><dl class="margin"><dd><p class="Body"><a name="83325" class="autotag"> </a>The following example illustrates a client-server XTI application and demonstrates the use of various XTI services. The client establishes a connection with the server, receives data from the server, and writes it to standard output. The server establishes a connection with the client and transfers data to the client.</p></dd></dl></dd></dl><dl class="margin"><dd><table border="0" cellpadding="3" cellspacing="0"><tr valign="top"><td valign="top" width="40"><a name="92028" class="autotag"><br></a><img border="0" alt="*" src="../../icons/note.gif"> </td><td><div class="Note"><hr><b class="symbol_UC">NOTE: </b> The transport provider,<b class="command"> /dev/tpit</b>, mentioned in <a href="streams.doc7.html#90839"><i class="title">Example 1</i></a> is not supported by Wind River Systems.<hr></div></td></tr></table></dd></dl><h4 class="EntityTitle"><a name="90839" class="autotag"><font face="Helvetica, sans-serif" size="-1" class="sans">Example 1 XTI Client-Server Program</font></a></h4><dl class="margin"><dd><font face="Helvetica, sans-serif" size="-1" class="sans"><h5 class="HU"><i><a name="90840" class="autotag">Client Program</a></i></h5></font><dl class="margin"><dd><pre class="Code"><a name="90841" class="autotag">#include "stdio.h"</a><a name="90842" class="autotag">#include "tiuser.h"</a><a name="90843" class="autotag">#include "fcntl.h"</a><a name="90844" class="autotag">#include "stropts.h"</a><a name="90845" class="autotag">#include "vxWorks.h"</a><a name="90846" class="autotag"></a><a name="90847" class="autotag">#define SRV_ADDR 1</a><a name="90848" class="autotag">void xtiClient( void )</a><a name="90849" class="autotag"> {</a><a name="90850" class="autotag"> int xFd; /* XTI endpoint descriptor */</a><a name="90851" class="autotag"> int nBytes; /* Number of bytes returned by t_rcv */</a><a name="90852" class="autotag"> int flags = 0; /* Flags passed to the t_rcv() call */</a><a name="90853" class="autotag"> char buf[30]; /* Buffer to store data in t_rcv */</a><a name="90854" class="autotag"> struct t_call *sndCall; /* sndCall parameter stores server's address */</a><a name="90855" class="autotag"> extern int t_errno; /* XLI errno variable */</a><a name="90856" class="autotag"></a><a name="90857" class="autotag"> /* The tliUserInit() call is used to make the TLI variable "t_errno"</a><a name="90858" class="autotag"> * a task variable, This call has to be made before any other XTI/TLI</a><a name="90859" class="autotag"> * services are used. </a><a name="90860" class="autotag"> */</a><a name="90861" class="autotag"> </a><a name="90862" class="autotag"> tliUserInit();</a><a name="90863" class="autotag"> </a><a name="90864" class="autotag"> /* Here the t_open call opens the transport provider named "tpit". </a><a name="90865" class="autotag"> * The first argument to t_open call is a transport provider </a><a name="90866" class="autotag"> * name. Here the /dev/tpit is a STREAMS clone device node that</a><a name="90867" class="autotag"> * identifies a connection-based transport protocol. The third</a><a name="90868" class="autotag"> * argument may be used to return the service characteristics of the </a><a name="90869" class="autotag"> * transport provider to the user. </a><a name="90870" class="autotag"> */ </a><a name="90871" class="autotag"> </a><a name="90872" class="autotag"> if(( xFd = t_open("/dev/tpit", O_RDWR, NULL)) < 0) </a><a name="90873" class="autotag"> {</a><a name="90874" class="autotag"> t_error("t_open failed\n");</a><a name="90875" class="autotag"> return;</a><a name="90876" class="autotag"> } </a><a name="90877" class="autotag"> </a><a name="90878" class="autotag"> /* The t_bind call is used to bind an transport endpoint to an port.</a><a name="90879" class="autotag"> * The first argument identifies the transport endpoint, the second </a><a name="90880" class="autotag"> * argument describes the address the user would like to bind to </a><a name="90881" class="autotag"> * the endpoint and the third argument is set on return from t_bind to</a><a name="90882" class="autotag"> * specify the address that the provider bound. Normally a client does </a><a name="90883" class="autotag"> * not care what its address is. A NULL second argument directs the </a><a name="90884" class="autotag"> * transport provider to choose an address for the user. </a><a name="90885" class="autotag"> */ </a><a name="90886" class="autotag"></a><a name="90887" class="autotag"> if(t_bind(xFd,NULL,NULL) <0)</a><a name="90888" class="autotag"> {</a><a name="90889" class="autotag"> t_error("t_bind failed\n");</a><a name="90890" class="autotag"> return;</a><a name="90891" class="autotag"> } </a><a name="90892" class="autotag"></a><a name="90893" class="autotag"> if((sndCall = (struct t_call *)t_alloc(xFd,T_CALL,T_ADDR)) == NULL) </a><a name="90894" class="autotag"> {</a><a name="90895" class="autotag"> t_error("t_alloc failed\n");</a><a name="90896" class="autotag"> return;</a><a name="90897" class="autotag"> } </a><a name="90898" class="autotag"></a><a name="90899" class="autotag"> sndCall->addr.len = sizeof(int) ;</a><a name="90900" class="autotag"> *(int *)sndCall->addr.buf = SRV_ADDR;</a><a name="90901" class="autotag"></a><a name="90902" class="autotag"> /* The t_connect call establishes the connection with the server, the</a><a name="90903" class="autotag"> * first argument to t_connect identifies the transport endpoint </a><a name="90904" class="autotag"> * through which the connection is established, the second argument </a><a name="90905" class="autotag"> * identifies the destination server. This argument is a pointer to a </a><a name="90906" class="autotag"> * t_call structure, The destination server address is the addr field</a><a name="90907" class="autotag"> * of the t_call structure. </a><a name="90908" class="autotag"> */</a><a name="90909" class="autotag"></a>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -