锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 褰撲竴涓猅CP榪炴帴寤虹珛鏃訛紝鍙戠敓浜嗕互涓嬪満鏅細 The server must be prepared to accept an incoming connection. This is normally done by calling socket, bind, and listen and is called a passive open. The client issues an active open by calling connect. This causes the client TCP to send a "synchronize" (SYN) segment, which tells the server the client's initial sequence number for the data that the client will send on the connection. Normally, there is no data sent with the SYN; it just contains an IP header, a TCP header, and possible TCP options (which we will talk about shortly). The server must acknowledge (ACK) the client's SYN and the server must also send its own SYN containing the initial sequence number for the data that the server will send on the connection. The server sends its SYN and the ACK of the client's SYN in a single segment. The client must acknowledge the server's SYN. 鏈灝戦渶瑕佷笁嬈″寘浜ゆ崲錛屽洜姝ょО浣淭CP鐨勪笁嬈℃彙鎵嬶紝濡備笅鍥炬墍紺猴細 We show the client's initial sequence number as J and the server's initial sequence number as K. The acknowledgment number in an ACK is the next expected sequence number for the end sending the ACK. Since a SYN occupies one byte of the sequence number space, the acknowledgment number in the ACK of each SYN is the initial sequence number plus one. Similarly, the ACK of each FIN is the sequence number of the FIN plus one. An everyday analogy for establishing a TCP connection is the telephone system [Nemeth 1997]. The socket function is the equivalent of having a telephone to use. bind is telling other people your telephone number so that they can call you. listen is turning on the ringer so that you will hear when an incoming call arrives. connect requires that we know the other person's phone number and dial it. accept is when the person being called answers the phone. Having the client's identity returned by accept (where the identify is the client's IP address and port number) is similar to having the caller ID feature show the caller's phone number. One difference, however, is that accept returns the client's identity only after the connection has been established, whereas the caller ID feature shows the caller's phone number before we choose whether to answer the phone or not. If the DNS is used (Chapter 11), it provides a service analogous to a telephone book. getaddrinfo is similar to looking up a person's phone number in the phone book. getnameinfo would be the equivalent of having a phone book sorted by telephone numbers that we could search, instead of a book sorted by name. MSS option. With this option, the TCP sending the SYN announces its maximum segment size, the maximum amount of data that it is willing to accept in each TCP segment, on this connection. The sending TCP uses the receiver's MSS value as the maximum size of a segment that it sends. We will see how to fetch and set this TCP option with the TCP_MAXSEG socket option (Section 7.9). Window scale option. The maximum window that either TCP can advertise to the other TCP is 65,535, because the corresponding field in the TCP header occupies 16 bits. But, high-speed connections, common in today's Internet (45 Mbits/sec and faster, as described in RFC 1323 [Jacobson, Braden, and Borman 1992]), or long delay paths (satellite links) require a larger window to obtain the maximum throughput possible. This newer option specifies that the advertised window in the TCP header must be scaled (left-shifted) by 0鈥?4 bits, providing a maximum window of almost one gigabyte (65,535 x 214). Both end-systems must support this option for the window scale to be used on a connection. We will see how to affect this option with the SO_RCVBUF socket option (Section 7.5). To provide interoperability with older implementations that do not support this option, the following rules apply. TCP can send the option with its SYN as part of an active open. But, it can scale its windows only if the other end also sends the option with its SYN. Similarly, the server's TCP can send this option only if it receives the option with the client's SYN. This logic assumes that implementations ignore options that they do not understand, which is required and common, but unfortunately, not guaranteed with all implementations. Timestamp option. This option is needed for high-speed connections to prevent possible data corruption caused by old, delayed, or duplicated segments. Since it is a newer option, it is negotiated similarly to the window scale option. As network programmers there is nothing we need to worry about with this option. These common options are supported by most implementations. The latter two are sometimes called the "RFC 1323 options," as that RFC [Jacobson, Braden, and Borman 1992] specifies the options. They are also called the "long fat pipe options," since a network with either a high bandwidth or a long delay is called a long fat pipe. Chapter 24 of TCPv1 contains more details on these options. TCP寤虹珛鏃墮渶瑕佷笁嬈¢氱煡錛岃岀粓姝竴涓猅CP榪炴帴鏃墮渶瑕佸洓嬈¢氱煡銆?br />One application calls close first, and we say that this end performs the active close. This end's TCP sends a FIN segment, which means it is finished sending data. The other end that receives the FIN performs the passive close. The received FIN is acknowledged by TCP. The receipt of the FIN is also passed to the application as an end-of-file (after any data that may have already been queued for the application to receive), since the receipt of the FIN means the application will not receive any additional data on the connection. Sometime later, the application that received the end-of-file will close its socket. This causes its TCP to send a FIN. The TCP on the system that receives this final FIN (the end that did the active close) acknowledges the FIN. Since a FIN and an ACK are required in each direction, four segments are normally required. We use the qualifier "normally" because in some scenarios, the FIN in Step 1 is sent with data. Also, the segments in Steps 2 and 3 are both from the end performing the passive close and could be combined into one segment. We show these packets in Figure 2.3. A FIN occupies one byte of sequence number space just like a SYN. Therefore, the ACK of each FIN is the sequence number of the FIN plus one. Between Steps 2 and 3 it is possible for data to flow from the end doing the passive close to the end doing the active close. This is called a half-close and we will talk about this in detail with the shutdown function in Section 6.6. The sending of each FIN occurs when a socket is closed. We indicated that the application calls close for this to happen, but realize that when a Unix process terminates, either voluntarily (calling exit or having the main function return) or involuntarily (receiving a signal that terminates the process), all open descriptors are closed, which will also cause a FIN to be sent on any TCP connection that is still open. Although we show the client in Figure 2.3 performing the active close, either end鈥攖he client or the server鈥攃an perform the active close. Often the client performs the active close, but with some protocols (notably HTTP/1.0), the server performs the active close. 鍏充簬TCP榪炴帴鐨勫緩绔嬪拰緇堟鎿嶄綔鍙互鐢變竴涓姸鎬佽漿鎹㈠浘鏉ヨ緇嗚鏄庯紝濡備笅鍥炬墍紺猴細 There are 11 different states defined for a connection and the rules of TCP dictate the transitions from one state to another, based on the current state and the segment received in that state. For example, if an application performs an active open in the CLOSED state, TCP sends a SYN and the new state is SYN_SENT. If TCP next receives a SYN with an ACK, it sends an ACK and the new state is ESTABLISHED. This final state is where most data transfer occurs. The two arrows leading from the ESTABLISHED state deal with the termination of a connection. If an application calls close before receiving a FIN (an active close), the transition is to the FIN_WAIT_1 state. But if an application receives a FIN while in the ESTABLISHED state (a passive close), the transition is to the CLOSE_WAIT state. We denote the normal client transitions with a darker solid line and the normal server transitions with a darker dashed line. We also note that there are two transitions that we have not talked about: a simultaneous open (when both ends send SYNs at about the same time and the SYNs cross in the network) and a simultaneous close (when both ends send FINs at the same time). Chapter 18 of TCPv1 contains examples and a discussion of both scenarios, which are possible but rare. One reason for showing the state transition diagram is to show the 11 TCP states with their names. These states are displayed by netstat, which is a useful tool when debugging client/server applications. We will use netstat to monitor state changes in Chapter 5. 涓嬪湡鏄劇ず浜嗕竴涓猅CP榪炴帴瀹為檯鍙戠敓鐨勫寘浜ゆ崲鎯呭喌錛氳繛鎺ュ緩绔嬶紝鏁版嵁浼犺緭鍜岃繛鎺ョ粓姝€傚湪姣忎竴绔紶杈撶殑鏃跺欙紝涔熺粰鍑轟簡TCP鐘舵併偮?br />TCP 榪炴帴鐨勫寘浜ゆ崲 The client in this example announces an MSS of 536 (indicating that it implements only the minimum reassembly buffer size) and the server announces an MSS of 1,460 (typical for IPv4 on an Ethernet). It is okay for the MSS to be different in each direction (see Exercise 2.5). Once a connection is established, the client forms a request and sends it to the server. We assume this request fits into a single TCP segment (i.e., less than 1,460 bytes given the server's announced MSS). The server processes the request and sends a reply, and we assume that the reply fits in a single segment (less than 536 in this example). We show both data segments as bolder arrows. Notice that the acknowledgment of the client's request is sent with the server's reply. This is called piggybacking and will normally happen when the time it takes the server to process the request and generate the reply is less than around 200 ms. If the server takes longer, say one second, we would see the acknowledgment followed later by the reply. (The dynamics of TCP data flow are covered in detail in Chapters 19 and 20 of TCPv1.) We then show the four segments that terminate the connection. Notice that the end that performs the active close (the client in this scenario) enters the TIME_WAIT state. We will discuss this in the next section. It is important to notice in Figure 2.5 that if the entire purpose of this connection was to send a one-segment request and receive a one-segment reply, there would be eight segments of overhead involved when using TCP. If UDP was used instead, only two packets would be exchanged: the request and the reply. But switching from TCP to UDP removes all the reliability that TCP provides to the application, pushing lots of these details from the transport layer (TCP) to the UDP application. Another important feature provided by TCP is congestion control, which must then be handled by the UDP application. Nevertheless, it is important to understand that many applications are built using UDP because the application exchanges small amounts of data and UDP avoids the overhead of TCP connection establishment and connection termination. Every implementation of TCP must choose a value for the MSL. The recommended value in RFC 1122 [Braden 1989] is 2 minutes, although Berkeley-derived implementations have traditionally used a value of 30 seconds instead. This means the duration of the TIME_WAIT state is between 1 and 4 minutes. The MSL is the maximum amount of time that any given IP datagram can live in a network. We know this time is bounded because every datagram contains an 8-bit hop limit (the IPv4 TTL field in Figure A.1 and the IPv6 hop limit field in Figure A.2) with a maximum value of 255. Although this is a hop limit and not a true time limit, the assumption is made that a packet with the maximum hop limit of 255 cannot exist in a network for more than MSL seconds. The way in which a packet gets "lost" in a network is usually the result of routing anomalies. A router crashes or a link between two routers goes down and it takes the routing protocols seconds or minutes to stabilize and find an alternate path. During that time period, routing loops can occur (router A sends packets to router B, and B sends them back to A) and packets can get caught in these loops. In the meantime, assuming the lost packet is a TCP segment, the sending TCP times out and retransmits the packet, and the retransmitted packet gets to the final destination by some alternate path. But sometime later (up to MSL seconds after the lost packet started on its journey), the routing loop is corrected and the packet that was lost in the loop is sent to the final destination. This original packet is called a lost duplicate or a wandering duplicate. TCP must handle these duplicates. There are two reasons for the TIME_WAIT state: To implement TCP's full-duplex connection termination reliably To allow old duplicate segments to expire in the network The first reason can be explained by looking at Figure 2.5 and assuming that the final ACK is lost. The server will resend its final FIN, so the client must maintain state information, allowing it to resend the final ACK. If it did not maintain this information, it would respond with an RST (a different type of TCP segment), which would be interpreted by the server as an error. If TCP is performing all the work necessary to terminate both directions of data flow cleanly for a connection (its full-duplex close), then it must correctly handle the loss of any of these four segments. This example also shows why the end that performs the active close is the end that remains in the TIME_WAIT state: because that end is the one that might have to retransmit the final ACK. To understand the second reason for the TIME_WAIT state, assume we have a TCP connection between 12.106.32.254 port 1500 and 206.168.112.219 port 21. This connection is closed and then sometime later, we establish another connection between the same IP addresses and ports: 12.106.32.254 port 1500 and 206.168.112.219 port 21. This latter connection is called an incarnation of the previous connection since the IP addresses and ports are the same. TCP must prevent old duplicates from a connection from reappearing at some later time and being misinterpreted as belonging to a new incarnation of the same connection. To do this, TCP will not initiate a new incarnation of a connection that is currently in the TIME_WAIT state. Since the duration of the TIME_WAIT state is twice the MSL, this allows MSL seconds for a packet in one direction to be lost, and another MSL seconds for the reply to be lost. By enforcing this rule, we are guaranteed that when we successfully establish a TCP connection, all old duplicates from previous incarnations of the connection have expired in the network. There is an exception to this rule. Berkeley-derived implementations will initiate a new incarnation of a connection that is currently in the TIME_WAIT state if the arriving SYN has a sequence number that is "greater than" the ending sequence number from the previous incarnation. Pages 958鈥?59 of TCPv2 talk about this in more detail. This requires the server to perform the active close, since the TIME_WAIT state must exist on the end that receives the next SYN. This capability is used by the rsh command. RFC 1185 [Jacobson, Braden, and Zhang 1990] talks about some pitfalls in doing this.
涓轟簡甯姪鎴戜滑鐞嗚Вconncet錛宎ccept錛宑lose榪欏嚑涓嚱鏁幫紝浠ュ強浣跨敤netstat宸ュ叿鏉ヨ皟璇昑CP搴旂敤紼嬪簭錛屾垜浠繀欏葷悊瑙CP榪炴帴鏄浣曞緩绔嬪拰緇堟鐨勫拰TCP鐘舵佽漿鎹㈠浘銆?br />涓夋鎻℃墜
鍥劇ず錛毬燭CP 鐨勪笁嬈℃彙鎵?/p>TCP 閫夐」
Each SYN can contain TCP options. Commonly used options include the following:
TCP 榪炴帴鐨勭粓姝?/h4>
Figure 2.3. Packets exchanged when a TCP connection is closed.
TCP 鐘舵佽漿鎹㈠浘
鍥劇ず錛歍CP 鐘舵佽漿鎹㈠浘瑙傚療鍖咃紙Watching the Packets錛?/h4>
TIME_WAIT 鐘舵?/h3>
姣棤鐤戦棶錛屽叧浜庣綉緇滅紪紼嬩腑鏈璁╀漢璇В鐐逛箣涓灝辨槸 TIME_WAIT聽鐘舵併?鍦ㄤ竴绔皟鐢ㄤ簡close涔嬪悗錛岃绔淮鎸佽繖涓姸鎬佺殑鏃墮棿涓轟袱鍊嶆渶澶ф鐢熷瓨鏃墮棿錛?span class="docEmphasis">maximum segment lifetime (MSL)錛夈?/h3>
]]>
摟1.3 涓涓畝鍗曠殑鏃ユ湡鏃墮棿鏈嶅姟鍣ㄧ▼搴忎唬鐮?br />聽聽聽榪欎釜鏈嶅姟鍣ㄧ▼搴忓彲浠ヤ負涓婁竴鑺傜殑瀹㈡埛绔彁渚涙湇鍔°?br />
1 #include "unp.h"
2 #include <time.h>
3 int
4 main(int argc, char **argv)
5 {
6 int listenfd, connfd;
7 struct sockaddr_in servaddr;
8 char buff[MAXLINE];
9 time_t ticks;
10 listenfd = Socket(AF_INET, SOCK_STREAM, 0);
11 bzeros(&servaddr, sizeof(servaddr));
12 servaddr.sin_family = AF_INET;
13 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
14 servaddr.sin_port = htons(13); /* daytime server */
15 Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
16 Listen(listenfd, LISTENQ);
17 for ( ; ; ) {
18 connfd = Accept(listenfd, (SA *) NULL, NULL);
19 ticks = time(NULL);
20 snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
21 Write(connfd, buff, strlen(buff));
22 Close(connfd);
23 }
24 }
11鈥?5 鏈嶅姟鍣ㄩ氳繃濉厖緗戠粶濂楁帴瀛楃粨鏋勪綋涓殑绔彛鍩燂紝浠ュ強鏈嶅姟鍣ㄧ殑緗戠粶鎺ュ彛錛圛P鍦板潃錛夛紝鐒跺悗榪涜緇戝畾錛堣皟鐢╞ind錛夈傚湪榪欓噷鎸囧畾IP鍦板潃涓篒NADDR_ANY錛屼負浜嗚瀹㈡埛绔彲浠ヨ繛鎺ユ湇鍔″櫒鐨勪換涓緗戠粶鎺ュ彛錛堝洜涓烘湇鍔″櫒鍙兘鏈夊鍧楃綉鍗★紝涔熷氨瀵瑰簲浜嗗涓狪P鍦板潃錛夛紝涔熷氨鏄濡傛灉鏈嶅姟鍣ㄦ湁涓や釜IP鍦板潃錛屽鎴風榪炴帴浠諱竴IP鍦板潃鍗沖彲銆傚悗緇珷鑺備腑浠嬬粛浜嗗浣曢檺鍒跺鎴風榪炴帴鍒頒竴涓浐瀹氱殑鎺ュ彛涓娿?/p>
16
閫氳繃璋冪敤listen錛屼竴涓鎺ュ瓧灝辮漿鎹負鐩戝惉濂楁帴瀛楋紝榪欏氨鏄璇ュ鎺ュ瓧璐熻矗鎺ユ敹鏉ヨ嚜瀹㈡埛绔殑榪炴帴璇鋒眰錛岃屽茍涓嶇湡姝d笌瀹㈡埛绔繘琛屼俊鎭紶杈撱?br />甯擱噺LISTENQ 鏄湪澶存枃浠?tt>unp.h涓畾涔夌殑錛屽畠鏄寚鑳藉鍚屾椂鐩戝惉瀹㈡埛绔繛鎺ョ殑涓暟銆備笉瓚呰繃LISTENQ鐨勫鎴風鍚屾椂榪炴帴鏈嶅姟鍣紝瀹冧滑浼氬湪涓涓槦鍒椾腑鎺掗槦錛屾潵絳夊緟鏈嶅姟鍣ㄧ殑澶勭悊銆傚悗緇珷鑺傛湁鏇磋緇嗙殑璁ㄨ銆?br />
鎺ユ敹瀹㈡埛绔繛鎺ワ紝鍙戦佸洖澶?/p>
17鈥?1 涓鑸湴錛屾湇鍔″櫒榪涚▼鍦ㄨ皟鐢╝ccept涔嬪悗榪涘叆鍒扮潯鐪犵姸鎬侊紝絳夊緟鐫瀹㈡埛绔湴榪炴帴璇鋒眰. 涓涓猅CP榪炴帴閫氳繃涓涓О涓轟笁鏂規彙鎵嬫潵寤虹珛錛屽綋涓夋柟鎻℃墜瀹屾垚涔嬪悗錛宎ccept璋冪敤榪斿洖銆傝繑鍥炲兼槸涓涓柊鐨勫鎺ュ瓧鎻忚堪絎︼紙涓涓暣鏁板糲onnfd錛夛紝榪欎釜鏂扮殑濂楁帴瀛楄礋璐d笌瀹㈡埛绔繘琛岄氳銆傚浜庢瘡涓涓鎴風鍦拌繛鎺ワ紝accept閮借繑鍥炰竴涓柊鐨勫鎺ュ瓧鎻忚堪絎︺傛暣鏈功浣跨敤鐨勬棤闄愬驚鐜鏍兼槸榪欐牱鐨勶細
for ( ; ; ) { . . . }
褰撳墠鏃墮棿鍜屾棩鏈熼氳繃璋冪敤搴撳嚱鏁皌ime鏉ヨ幏寰楋紝騫朵笖閫氳繃璋冪敤ctime榪涜杞崲錛屼嬌寰楁垜浠兘澶熺洿瑙傜殑闃呰銆傚涓嬶細
Mon May 26 20:58:40 2003
22
瀹㈡埛绔皟鐢╟lose涔嬪悗錛屾湇鍔″櫒鍏抽棴榪炴帴銆傝繖鏃跺欏紩璧蜂簡涓涓猅CP榪炴帴緇堟搴忓垪錛氫竴涓狥IN鍙戦佸埌姣忎竴绔紝鍚屾椂姣忎竴涓狥IN閮借琚彟涓绔‘璁ゃ傚湪鍚庨潰绔犺妭涓皢浼氬TCP榪炴帴寤虹珛鏃跺欑殑涓夋柟鎻℃墜浠ュ強TCP榪炴帴緇堟鏃跺欑殑鍥涘寘浜ゆ崲鏈夋洿璇︾粏鐨勮璁恒?br />聽聽聽浠ヤ笂緇欏嚭鐨勫鎴風鍜屾湇鍔″櫒鐗堟湰閮芥槸鍗忚鐩稿叧鐨勶紙IPv4錛夛紝鍦ㄥ悗闈㈠皢浼氱粰鍑轟竴涓崗璁棤鍏崇殑鐗堟湰錛圛Pv4鍜孖Pv6閮介傜敤錛屼富瑕侀氳繃浣跨敤getaddrinfo鍑芥暟錛夈?br />聽聽聽鏈鍚庨渶瑕佽ˉ鍏呯殑涓鐐規槸錛屽湪浠ヤ笂娑夊強鍒癝ocket API璋冪敤鐨勬椂鍊欙紝姣忎釜鍑芥暟鐨勭涓涓瓧姣嶅彉鎴愪簡澶у啓錛屽叾鎰忎箟鍜屽皬鍐欏紑澶寸殑鏄竴鏍風殑錛屽彧涓嶈繃澶氫簡涓涓敊璇鐞嗙艦浜嗐?/p>
鍥韭?.2 鏈嶅姟鍣ㄥ悓鏃跺鐞嗗涓鎴風
摟1.2 浠g爜紺轟緥鍜岃В璇?/p>
1 #include聽 "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5聽聽聽聽 int聽聽聽聽 sockfd, n;
6聽聽聽聽 char聽聽聽 recvline[MAXLINE + 1];
7聽聽聽聽 struct sockaddr_in servaddr;
8聽聽聽聽 if (argc != 2)
9聽聽聽聽聽聽聽聽 err_quit("usage: a.out <IPaddress>");
10聽聽聽聽 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
11聽聽聽聽聽聽聽聽 err_sys("socket error");
12聽聽聽聽 bzero(&servaddr, sizeof(servaddr));
13聽聽聽聽 servaddr.sin_family = AF_INET;
14聽聽聽聽 servaddr.sin_port = htons(13);聽 /* daytime server */
15聽聽聽聽 if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
16聽聽聽聽聽聽聽聽 err_quit("inet_pton error for %s", argv[1]);
17聽聽聽聽 if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
18聽聽聽聽聽聽聽聽 err_sys("connect error");
19聽聽聽聽 while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
20聽聽聽聽聽聽聽聽 recvline[n] = 0;聽聽聽聽聽聽聽 /* null terminate */
21聽聽聽聽聽聽聽聽 if (fputs(recvline, stdout) == EOF)
22聽聽聽聽聽聽聽聽聽聽聽聽 err_sys("fputs error");
23聽聽聽聽 }
24聽聽聽聽 if (n < 0)
25聽聽聽聽聽聽聽聽 err_sys("read error");
26聽聽聽聽 exit(0);
27 }
鍏朵腑unp.h鏄嚜瀹氫箟鐨勫ご鏂囦歡錛?a class="" title="unp.h鏂囦歡鍐呭" href="/sscchh-2000/archive/2006/05/09/6836.html" target="_blank">鏌ョ湅婧愪唬鐮?/a>銆傛垜浠紪璇戝茍鎵ц浠ヤ笂浠g爜錛屽緱鍒頒互涓嬭緭鍑虹粨鏋滐細
solaris %a.out 206.168.112.96聽聽聽聽 our input | |
Mon May 26 20:58:40 2003聽聽聽聽聽聽聽聽聽聽the program's output |
1 璇ュご鏂囦歡鍖呭惈浜嗗ぇ澶氭暟緗戠粶紼嬪簭鎵闇瑕佺殑澶氫釜澶存枃浠朵互鍙婂畾涔変簡鎴戜滑灝嗚浣跨敤鐨勪竴浜涘父閲?渚嬪 MAXLINE).
10鈥?1 socket鍑芥暟璋冪敤鍒涘緩浜嗕竴涓綉緇滄祦濂楁帴瀛?(Internet (AF_INET) stream (SOCK_STREAM) socket), 璇ュ嚱鏁拌繑鍥炰竴涓暣鏁板?瀹冩弿榪頒簡璇ュ鎺ュ瓧,浠ュ悗鐨勫嚱鏁伴氳繃璇ユ暣鏁板兼潵浣跨敤榪欎釜濂楁帴瀛?渚嬪connect鍜宺ead絳夎皟鐢?. 鍏朵腑err_寮澶寸殑鍑芥暟鏄垜浠嚜瀹氫箟鐨勫嚱鏁?璇﹁榪欓噷.
Mon May 26 20 : 58 : 40 2003\r\n
\r 鏄洖杞? \n 鏄崲琛?
緇堟紼嬪簭
26 exit 緇堟紼嬪簭.Unix鍦ㄤ竴涓繘紼嬬粨鏉熸椂鍊欐繪槸鍏抽棴鎵鏈夋墦寮鐨勬弿榪扮,鍥犳鎴戜滑鐨凾CP濂楁帴瀛楁鏃跺叧闂簡.
鍚庣畫鍐呭灝嗗姝ゆ湁鏇存繁鍏ョ殑璁ㄨ.