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

📄 main.html

📁 最新的免费嵌入式系统TCP/IP协议栈!
💻 HTML
📖 第 1 页 / 共 5 页
字号:
    s-&gt;textlen = 6;  }}<span class="keyword">static</span> <span class="keywordtype">void</span> acked(<span class="keywordtype">void</span>) {  <span class="keyword">struct </span>example6_state *s = (<span class="keyword">struct </span>example6_state *)<a class="code" href="a00150.html#g788ffac72342f6172343d7f8099cbe1a">uip_conn</a>-&gt;<a class="code" href="a00088.html#97f9e1fda815bfb8b1f4577c355ade20">appstate</a>;    s-&gt;textlen -= <a class="code" href="a00150.html#g788ffac72342f6172343d7f8099cbe1a">uip_conn</a>-&gt;<a class="code" href="a00088.html#0ef3ae2764714bf90620075c374c262e">len</a>;  s-&gt;textptr += <a class="code" href="a00150.html#g788ffac72342f6172343d7f8099cbe1a">uip_conn</a>-&gt;<a class="code" href="a00088.html#0ef3ae2764714bf90620075c374c262e">len</a>;  <span class="keywordflow">if</span>(s-&gt;textlen == 0) {    <span class="keywordflow">switch</span>(s-&gt;state) {    <span class="keywordflow">case</span> STATE_HELLO:      s-&gt;state   = STATE_WORLD;      s-&gt;textptr = <span class="stringliteral">"world!\n"</span>;      s-&gt;textlen = 7;      <span class="keywordflow">break</span>;    <span class="keywordflow">case</span> STATE_WORLD:      <a class="code" href="a00147.html#g61db1dcb7c760e4dd5d60bf4e5576dca">uip_close</a>();      <span class="keywordflow">break</span>;    }  }}<span class="keyword">static</span> <span class="keywordtype">void</span> senddata(<span class="keywordtype">void</span>) {  <span class="keyword">struct </span>example6_state *s = (<span class="keyword">struct </span>example6_state *)<a class="code" href="a00150.html#g788ffac72342f6172343d7f8099cbe1a">uip_conn</a>-&gt;<a class="code" href="a00088.html#97f9e1fda815bfb8b1f4577c355ade20">appstate</a>;  <span class="keywordflow">if</span>(s-&gt;textlen &gt; 0) {    <a class="code" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send</a>(s-&gt;textptr, s-&gt;textlen);  }}</pre></div><p>The application state consists of a "state" variable, a "textptr" pointer to a text message and the "textlen" length of the text message. The "state" variable can be either "STATE_WAITING", meaning that the application is waiting for data to arrive from the network, "STATE_HELLO", in which the application is sending the "Hello" part of the message, or "STATE_WORLD", in which the application is sending the "world!" message.<p>The application does not handle errors or connection closing events, and therefore the aborted(), timedout() and closed() functions are implemented as empty functions.<p>The connected() function will be called when a connection has been established, and in this case sets the "state" variable to be "STATE_WAITING" and the "textlen" variable to be zero, indicating that there is no message to be sent out.<p>When new data arrives from the network, the newdata() function will be called by the event handler function. The newdata() function will check if the connection is in the "STATE_WAITING" state, and if so switches to the "STATE_HELLO" state and registers a 6 byte long "Hello " message with the connection. This message will later be sent out by the senddata() function.<p>The acked() function is called whenever data that previously was sent has been acknowleged by the receiving host. This acked() function first reduces the amount of data that is left to send, by subtracting the length of the previously sent data (obtained from "uip_conn-&gt;len") from the "textlen" variable, and also adjusts the "textptr" pointer accordingly. It then checks if the "textlen" variable now is zero, which indicates that all data now has been successfully received, and if so changes application state. If the application was in the "STATE_HELLO" state, it switches state to "STATE_WORLD" and sets up a 7 byte "world!\n" message to be sent. If the application was in the "STATE_WORLD" state, it closes the connection.<p>Finally, the senddata() function takes care of actually sending the data that is to be sent. It is called by the event handler function when new data has been received, when data has been acknowledged, when a new connection has been established, when the connection is polled because of inactivity, or when a retransmission should be made. The purpose of the senddata() function is to optionally format the data that is to be sent, and to call the <a class="el" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send()</a> function to actually send out the data. In this particular example, the function simply calls <a class="el" href="a00147.html#g04b053a623aac7cd4195157d470661b3">uip_send()</a> with the appropriate arguments if data is to be sent, after checking if data should be sent out or not as indicated by the "textlen" variable.<p>It is important to note that the senddata() function never should affect the application state; this should only be done in the acked() and newdata() functions.<h2><a class="anchor" name="protoimpl">Protocol Implementations</a></h2>The protocols in the TCP/IP protocol suite are designed in a layered fashion where each protocol performs a specific function and the interactions between the protocol layers are strictly defined. While the layered approach is a good way to design protocols, it is not always the best way to implement them. In uIP, the protocol implementations are tightly coupled in order to save code space.<p>This section gives detailed information on the specific protocol implementations in uIP.<h3><a class="anchor" name="ip">IP --- Internet Protocol</a></h3>When incoming packets are processed by uIP, the IP layer is the first protocol that examines the packet. The IP layer does a few simple checks such as if the destination IP address of the incoming packet matches any of the local IP address and verifies the IP header checksum. Since there are no IP options that are strictly required and because they are very uncommon, any IP options in received packets are dropped.<h4><a class="anchor" name="ipreass">IP Fragment Reassembly</a></h4>IP fragment reassembly is implemented using a separate buffer that holds the packet to be reassembled. An incoming fragment is copied into the right place in the buffer and a bit map is used to keep track of which fragments have been received. Because the first byte of an IP fragment is aligned on an 8-byte boundary, the bit map requires a small amount of memory. When all fragments have been reassembled, the resulting IP packet is passed to the transport layer. If all fragments have not been received within a specified time frame, the packet is dropped.<p>The current implementation only has a single buffer for holding packets to be reassembled, and therefore does not support simultaneous reassembly of more than one packet. Since fragmented packets are uncommon, this ought to be a reasonable decision. Extending the implementation to support multiple buffers would be straightforward, however.<h4><a class="anchor" name="ipbroadcast">Broadcasts and Multicasts</a></h4>IP has the ability to broadcast and multicast packets on the local network. Such packets are addressed to special broadcast and multicast addresses. Broadcast is used heavily in many UDP based protocols such as the Microsoft Windows file-sharing SMB protocol. Multicast is primarily used in protocols used for multimedia distribution such as RTP. TCP is a point-to-point protocol and does not use broadcast or multicast packets. uIP current supports broadcast packets as well as sending multicast packets. Joining multicast groups (IGMP) and receiving non-local multicast packets is not currently supported.<h3><a class="anchor" name="icmp">ICMP --- Internet Control Message Protocol</a></h3>The ICMP protocol is used for reporting soft error conditions and for querying host parameters. Its main use is, however, the echo mechanism which is used by the "ping" program.<p>The ICMP implementation in uIP is very simple as itis restricted to only implement ICMP echo messages. Replies to echo messages are constructed by simply swapping the source and destination IP addresses of incoming echo requests and rewriting the ICMP header with the Echo-Reply message type. The ICMP checksum is adjusted using standard techniques (see RFC1624).<p>Since only the ICMP echo message is implemented, there is no support for Path MTU discovery or ICMP redirect messages. Neither of these is strictly required for interoperability; they are performance enhancement mechanisms.<h3><a class="anchor" name="tcp">TCP --- Transmission Control Protocol</a></h3>The TCP implementation in uIP is driven by incoming packets and timer events. Incoming packets are parsed by TCP and if the packet contains data that is to be delivered to the application, the application is invoked by the means of the application function call. If the incoming packet acknowledges previously sent data, the connection state is updated and the application is informed, allowing it to send out new data.<h4><a class="anchor" name="listeb">Listening Connections</a></h4>TCP allows a connection to listen for incoming connection requests. In uIP, a listening connection is identified by the 16-bit port number and incoming connection requests are checked against the list of listening connections. This list of listening connections is dynamic and can be altered by the applications in the system.<h4><a class="anchor" name="slidingwindow">Sliding Window</a></h4>Most TCP implementations use a sliding window mechanism for sending data. Multiple data segments are sent in succession without waiting for an acknowledgment for each segment.<p>The sliding window algorithm uses a lot of 32-bit operations and because 32-bit arithmetic is fairly expensive on most 8-bit CPUs, uIP does not implement it. Also, uIP does not buffer sent packets and a sliding window implementation that does not buffer sent packets will have to be supported by a complex application layer. Instead, uIP allows only a single TCP segment per connection to be unacknowledged at any given time.<p>It is important to note that even though most TCP implementations use the sliding window algorithm, it is not required by the TCP specifications. Removing the sliding window mechanism does not affect interoperability in any way.<h4><a class="anchor" name="rttest">Round-Trip Time Estimation</a></h4>TCP continuously estimates the current Round-Trip Time (RTT) of every active connection in order to find a suitable value for the retransmission time-out.<p>The RTT estimation in uIP is implemented using TCP's periodic timer. Each time the periodic timer fires, it increments a counter for each connection that has unacknowledged data in the network. When an acknowledgment is received, the current value of the counter is used as a sample of the RTT. The sample is used together with Van Jacobson's standard TCP RTT estimation function to calculate an estimate of the RTT. Karn's algorithm is used to ensure that retransmissions do not skew the estimates.<h4><a class="anchor" name="rexmit">Retransmissions</a></h4>Retransmissions are driven by the periodic TCP timer. Every time the periodic timer is invoked, the retransmission timer for each connection is decremented. If the timer reaches zero, a retransmission should be made.<p>As uIP does not keep track of packet contents after they have been sent by the device driver, uIP requires that the application takes an active part in performing the retransmission. When uIP decides that a segment should be retransmitted, it calls the application with a flag set indicating that a retransmission is required. The application checks the retransmission flag and produces the same data that was previously sent. From the application's standpoint, performing a retransmission is not different from how the data originally was sent. Therefore the application can be written in such a way that the same code is used both for sending data and retransmitting data. Also, it is important to note that even though the actual retransmission operation is carried out by the application, it is the responsibility of the stack to know when the retransmission should be made. Thus the complexity of the application does not necessarily increase because it takes an active part in doing retransmissions.<h4><a class="anchor" name="flowcontrol">Flow Control</a></h4>The purpose of TCP's flow control mechanisms is to allow communication between hosts with wildly varying memory dimensions. In each TCP segment, the sender of the segment indicates its available buffer space. A TCP sender must not send more data than the buffer space indicated by the receiver.<p>In uIP, the application cannot send more data than the receiving host can buffer. And application cannot send more data than the amount of bytes it is allowed to send by the receiving host. If the remote host cannot accept any data at all, the stack initiates the zero window probing mechanism.<h4><a class="anchor" name="congestioncontrol">Congestion Control</a></h4>The congestion control mechanisms limit the number of simultaneous TCP segments in the network. The algorithms used for congestion control are designed to be simple to implement and require only a few lines of code.<p>Since uIP only handles one in-flight TCP segment per connection, the amount of simultaneous segments cannot be further limited, thus the congestion control mechanisms are not needed.<h4><a class="anchor" name="urgdata">Urgent Data</a></h4>TCP's urgent data mechanism provides an application-to-application notification mechanism, which can be used by an application to mark parts of the data stream as being more urgent than the normal stream. It is up to the receiving application to interpret the meaning of the urgent data.<p>In many TCP implementations, including the BSD implementation, the urgent data feature increases the complexity of the implementation because it requires an asynchronous notification mechanism in an otherwise synchronous API. As uIP already use an asynchronous event based API, the implementation of the urgent data feature does not lead to increased complexity.<h2><a class="anchor" name="performance">Performance</a></h2>In TCP/IP implementations for high-end systems, processing time is dominated by the checksum calculation loop, the operation of copying packet data and context switching. Operating systems for high-end systems often have multiple protection domains for protecting kernel data from user processes and user processes from each other. Because the TCP/IP stack is run in the kernel, data has to be copied between the kernel space and the address space of the user processes and a context switch has to be performed once the data has been copied. Performance can be enhanced by combining the copy operation with the checksum calculation. Because high-end systems usually have numerous active connections, packet demultiplexing is also an expensive operation.<p>A small embedded device does not have the necessary processing power to have multiple protection domains and the power to run a multitasking operating system. Therefore there is no need to copy data between the TCP/IP stack and the application program. With an event based API there is no context switch between the TCP/IP stack and the applications.<p>In such limited systems, the TCP/IP processing overhead is dominated by the copying of packet data from the network device to host memory, and checksum calculation. Apart from the checksum calculation and copying, the TCP processing done for an incoming packet involves only updating a few counters and flags before handing the data over to the application. Thus an estimate of the CPU overhead of our TCP/IP implementations can be obtained by calculating the amount of CPU cycles needed for the checksum calculation and copying of a maximum sized packet.<h3><a class="ancho

⌨️ 快捷键说明

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