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

📄 main.html

📁 UIP完整的协议栈
💻 HTML
📖 第 1 页 / 共 5 页
字号:
If the connection has been closed by the remote end, the test function <a class="el" href="a00147.html#gef6c4140c632b6a406779342cf3b6eb6">uip_closed()</a> is true. The application may then do any necessary cleanups.<h4><a class="anchor" name="errors">Reporting Errors</a></h4>There are two fatal errors that can happen to a connection, either that the connection was aborted by the remote host, or that the connection retransmitted the last data too many times and has been aborted. uIP reports this by calling the application function. The application can use the two test functions <a class="el" href="a00147.html#gfbd5fc486dfdf6bf6fc9db52b1f418c4">uip_aborted()</a> and <a class="el" href="a00147.html#g7b2ac4b18bd2ac3912fe67b3b17158c3">uip_timedout()</a> to test for those error conditions.<h4><a class="anchor" name="polling">Polling</a></h4>When a connection is idle, uIP polls the application every time the periodic timer fires. The application uses the test function <a class="el" href="a00147.html#g58bb90796c1cdad3aac2ecf44d87b20e">uip_poll()</a> to check if it is being polled by uIP.<p>The polling event has two purposes. The first is to let the application periodically know that a connection is idle, which allows the application to close connections that have been idle for too long. The other purpose is to let the application send new data that has been produced. The application can only send data when invoked by uIP, and therefore the poll event is the only way to send data on an otherwise idle connection.<h4><a class="anchor" name="listen">Listening Ports</a></h4>uIP maintains a list of listening TCP ports. A new port is opened for listening with the <a class="el" href="a00147.html#gdd1ab3704ecd4900eec61a6897d32dc8">uip_listen()</a> function. When a connection request arrives on a listening port, uIP creates a new connection and calls the application function. The test function <a class="el" href="a00147.html#gdb971fb1525d0c5002f52125b05f3218">uip_connected()</a> is true if the application was invoked because a new connection was created.<p>The application can check the lport field in the <a class="el" href="a00088.html">uip_conn</a> structure to check to which port the new connection was connected.<h4><a class="anchor" name="connect">Opening Connections</a></h4>New connections can be opened from within uIP by the function <a class="el" href="a00147.html#g8096b0c4b543dc408f4dd031ddae7240">uip_connect()</a>. This function allocates a new connection and sets a flag in the connection state which will open a TCP connection to the specified IP address and port the next time the connection is polled by uIP. The <a class="el" href="a00147.html#g8096b0c4b543dc408f4dd031ddae7240">uip_connect()</a> function returns a pointer to the <a class="el" href="a00088.html">uip_conn</a> structure for the new connection. If there are no free connection slots, the function returns NULL.<p>The function <a class="el" href="a00148.html#g87f0b54ade0d159fba495089128a4932">uip_ipaddr()</a> may be used to pack an IP address into the two element 16-bit array used by uIP to represent IP addresses.<p>Two examples of usage are shown below. The first example shows how to open a connection to TCP port 8080 of the remote end of the current connection. If there are not enough TCP connection slots to allow a new connection to be opened, the <a class="el" href="a00147.html#g8096b0c4b543dc408f4dd031ddae7240">uip_connect()</a> function returns NULL and the current connection is aborted by <a class="el" href="a00147.html#g88d2ccf7cd821f89d9a8df7e3948b56c">uip_abort()</a>.<p><div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> connect_example1_app(<span class="keywordtype">void</span>) {   <span class="keywordflow">if</span>(<a class="code" href="a00147.html#g8096b0c4b543dc408f4dd031ddae7240">uip_connect</a>(<a class="code" href="a00088.html">uip_conn</a>-&gt;ripaddr, <a class="code" href="a00148.html#g69a7a4951ff21b302267532c21ee78fc">HTONS</a>(8080)) == <a class="code" href="a00160.html#g070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>) {      <a class="code" href="a00147.html#g88d2ccf7cd821f89d9a8df7e3948b56c">uip_abort</a>();   }}   </pre></div><p>The second example shows how to open a new connection to a specific IP address. No error checks are made in this example.<p><div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> connect_example2(<span class="keywordtype">void</span>) {   <a class="code" href="a00153.html#g77570ac4fcab86864fa1916e55676da2">u16_t</a> ipaddr[2];   <a class="code" href="a00148.html#g87f0b54ade0d159fba495089128a4932">uip_ipaddr</a>(ipaddr, 192,168,0,1);   <a class="code" href="a00147.html#g8096b0c4b543dc408f4dd031ddae7240">uip_connect</a>(ipaddr, <a class="code" href="a00148.html#g69a7a4951ff21b302267532c21ee78fc">HTONS</a>(8080));}</pre></div><h2><a class="anchor" name="examples">Examples</a></h2>This section presents a number of very simple uIP applications. The uIP code distribution contains several more complex applications.<h3><a class="anchor" name="example1">A Very Simple Application</a></h3>This first example shows a very simple application. The application listens for incoming connections on port 1234. When a connection has been established, the application replies to all data sent to it by saying "ok"<p>The implementation of this application is shown below. The application is initialized with the function called example1_init() and the uIP callback function is called example1_app(). For this application, the configuration variable UIP_APPCALL should be defined to be example1_app().<p><div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> example1_init(<span class="keywordtype">void</span>) {   <a class="code" href="a00147.html#gdd1ab3704ecd4900eec61a6897d32dc8">uip_listen</a>(<a class="code" href="a00148.html#g69a7a4951ff21b302267532c21ee78fc">HTONS</a>(1234));}<span class="keywordtype">void</span> example1_app(<span class="keywordtype">void</span>) {   <span class="keywordflow">if</span>(<a class="code" href="a00147.html#g26a14b8dae3f861830af9e7cf1e03725">uip_newdata</a>() || <a class="code" href="a00147.html#ga8933ad15a2e2947dae4a5cff50e6007">uip_rexmit</a>()) {      <a class="code" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send</a>(<span class="stringliteral">"ok\n"</span>, 3);   }}</pre></div><p>The initialization function calls the uIP function <a class="el" href="a00147.html#gdd1ab3704ecd4900eec61a6897d32dc8">uip_listen()</a> to register a listening port. The actual application function example1_app() uses the test functions <a class="el" href="a00147.html#g26a14b8dae3f861830af9e7cf1e03725">uip_newdata()</a> and <a class="el" href="a00147.html#ga8933ad15a2e2947dae4a5cff50e6007">uip_rexmit()</a> to determine why it was called. If the application was called because the remote end has sent it data, it responds with an "ok". If the application function was called because data was lost in the network and has to be retransmitted, it also sends an "ok". Note that this example actually shows a complete uIP application. It is not required for an application to deal with all types of events such as <a class="el" href="a00147.html#gdb971fb1525d0c5002f52125b05f3218">uip_connected()</a> or <a class="el" href="a00147.html#g7b2ac4b18bd2ac3912fe67b3b17158c3">uip_timedout()</a>.<h3><a class="anchor" name="example2">A More Advanced Application</a></h3>This second example is slightly more advanced than the previous one, and shows how the application state field in the <a class="el" href="a00088.html">uip_conn</a> structure is used.<p>This application is similar to the first application in that it listens to a port for incoming connections and responds to data sent to it with a single "ok". The big difference is that this application prints out a welcoming "Welcome!" message when the connection has been established.<p>This seemingly small change of operation makes a big difference in how the application is implemented. The reason for the increase in complexity is that if data should be lost in the network, the application must know what data to retransmit. If the "Welcome!" message was lost, the application must retransmit the welcome and if one of the "ok" messages is lost, the application must send a new "ok".<p>The application knows that as long as the "Welcome!" message has not been acknowledged by the remote host, it might have been dropped in the network. But once the remote host has sent an acknowledgment back, the application can be sure that the welcome has been received and knows that any lost data must be an "ok" message. Thus the application can be in either of two states: either in the WELCOME-SENT state where the "Welcome!" has been sent but not acknowledged, or in the WELCOME-ACKED state where the "Welcome!" has been acknowledged.<p>When a remote host connects to the application, the application sends the "Welcome!" message and sets it's state to WELCOME-SENT. When the welcome message is acknowledged, the application moves to the WELCOME-ACKED state. If the application receives any new data from the remote host, it responds by sending an "ok" back.<p>If the application is requested to retransmit the last message, it looks at in which state the application is. If the application is in the WELCOME-SENT state, it sends a "Welcome!" message since it knows that the previous welcome message hasn't been acknowledged. If the application is in the WELCOME-ACKED state, it knows that the last message was an "ok" message and sends such a message.<p>The implementation of this application is seen below. This configuration settings for the application is follows after its implementation.<p><div class="fragment"><pre class="fragment"><span class="keyword">struct </span>example2_state {   <span class="keyword">enum</span> {WELCOME_SENT, WELCOME_ACKED} state;};<span class="keywordtype">void</span> example2_init(<span class="keywordtype">void</span>) {   <a class="code" href="a00147.html#gdd1ab3704ecd4900eec61a6897d32dc8">uip_listen</a>(<a class="code" href="a00148.html#g69a7a4951ff21b302267532c21ee78fc">HTONS</a>(2345));}<span class="keywordtype">void</span> example2_app(<span class="keywordtype">void</span>) {   <span class="keyword">struct </span>example2_state *s;   s = (<span class="keyword">struct </span>example2_state *)<a class="code" href="a00088.html">uip_conn</a>-&gt;appstate;      <span class="keywordflow">if</span>(<a class="code" href="a00147.html#gdb971fb1525d0c5002f52125b05f3218">uip_connected</a>()) {      s-&gt;state = WELCOME_SENT;      <a class="code" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send</a>(<span class="stringliteral">"Welcome!\n"</span>, 9);      <span class="keywordflow">return</span>;   }    <span class="keywordflow">if</span>(<a class="code" href="a00147.html#gde6634974418e3240c212b9b16864368">uip_acked</a>() &amp;&amp; s-&gt;state == WELCOME_SENT) {      s-&gt;state = WELCOME_ACKED;   }   <span class="keywordflow">if</span>(<a class="code" href="a00147.html#g26a14b8dae3f861830af9e7cf1e03725">uip_newdata</a>()) {      <a class="code" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send</a>(<span class="stringliteral">"ok\n"</span>, 3);   }   <span class="keywordflow">if</span>(<a class="code" href="a00147.html#ga8933ad15a2e2947dae4a5cff50e6007">uip_rexmit</a>()) {      <span class="keywordflow">switch</span>(s-&gt;state) {      <span class="keywordflow">case</span> WELCOME_SENT:         <a class="code" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send</a>(<span class="stringliteral">"Welcome!\n"</span>, 9);         <span class="keywordflow">break</span>;

⌨️ 快捷键说明

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