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

📄 tcpconnection.sm

📁 SMC takes a state machine stored in a .sm file and generates a State pattern in twelve programming l
💻 SM
📖 第 1 页 / 共 2 页
字号:
// -*- tab-width: 4; -*-%{//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL/// // Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.// // The Original Code is State Machine Compiler (SMC).// // The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2000 - 2007. Charles W. Rapp.// All Rights Reserved.// // Contributor(s): //// Name//  TcpConnection.sm//// Description//  The TCP/IP state transition diagram.//// RCS ID// $Id: TcpConnection.sm,v 1.7 2007/12/28 12:34:40 cwrapp Exp $//// CHANGE LOG// $Log: TcpConnection.sm,v $// Revision 1.7  2007/12/28 12:34:40  cwrapp// Version 5.0.1 check-in.//// Revision 1.6  2005/11/07 19:34:54  cwrapp// Changes in release 4.3.0:// New features://// + Added -reflect option for Java, C#, VB.Net and Tcl code//   generation. When used, allows applications to query a state//   about its supported transitions. Returns a list of transition//   names. This feature is useful to GUI developers who want to//   enable/disable features based on the current state. See//   Programmer's Manual section 11: On Reflection for more//   information.//// + Updated LICENSE.txt with a missing final paragraph which allows//   MPL 1.1 covered code to work with the GNU GPL.//// + Added a Maven plug-in and an ant task to a new tools directory.//   Added Eiten Suez's SMC tutorial (in PDF) to a new docs//   directory.//// Fixed the following bugs://// + (GraphViz) DOT file generation did not properly escape//   double quotes appearing in transition guards. This has been//   corrected.//// + A note: the SMC FAQ incorrectly stated that C/C++ generated//   code is thread safe. This is wrong. C/C++ generated is//   certainly *not* thread safe. Multi-threaded C/C++ applications//   are required to synchronize access to the FSM to allow for//   correct performance.//// + (Java) The generated getState() method is now public.//// Revision 1.5  2005/05/28 13:31:18  cwrapp// Updated C++ examples.//// Revision 1.0  2003/12/14 19:41:10  charlesr// Initial revision//%}%class TcpConnection%header TcpConnection.h%include "TcpSegment.h"%start MainMap::CLOSED%map MainMap%%CLOSED{    PassiveOpen(port: unsigned short)        ServiceOpening        {            openServerSocket(port);        }    ActiveOpen(address: const sockaddr_in*)        ClientOpening        {            openClientSocket(address);        }    AcceptOpen(segment: const TcpSegment&)        SYN_RCVD        {            sendSynAck(segment);            setNearAddress();        }    // Ignore close requests when closed.    Close        nil        {}}// Wait here until service open has either succeeded or failed.ServiceOpening{    ServerOpened        LISTEN        {            openSuccess();        }    OpenFailed(reason: const char*)        CLOSED        {            closeSocket();            openFailed(reason);        }}// Wait here until client open has either succeeded or failed.ClientOpening{    ClientOpened(address: const sockaddr_in*)        SYN_SENT        {            sendOpenSyn(address);        }    OpenFailed(reason: const char*)        CLOSED        {            closeSocket();            openFailed(reason);        }}// Server sockets just sit here, creating new client sockets when// a SYN is received.LISTEN{    // Create a new client socket and send its port number in    // the SYN/ACK response.    SYN(segment: const TcpSegment&)        nil        {            accept(segment);            deleteSegment(segment);        }    Close        CLOSED        {            closeSocket();            closed("");        }    // But don't reset a reset message because there is no    // connection to reset.    RST(segment: const TcpSegment&)        nil        {            deleteSegment(segment);        }    // Don't die on an undefined segment either.    UNDEF(segment: const TcpSegment&)        nil        {            doSend(TcpSegment::RST,                   NULL,                   0,                   0,                   &segment);            deleteSegment(segment);        }}// An "accepted" client socket starts life in this state.SYN_RCVDEntry{    startTimer("ACK_TIMER", TcpConnection::ACK_TIMEOUT);}Exit{    stopTimer("ACK_TIMER");}{    // The connection was reset before it was established.    // Close the datagram socket but don't tell anybody.    RST(segment: const TcpSegment&)        CLOSED        {            closeSocket();            clearListener();            deleteSegment(segment);        }    // The TCP state transition diagram shows the server socket    // taking an ACK transtion to the ESTABLISHED state but that    // is not quite true. The accepted client socket goes to    // the ESTABLISHED state while the server socket goes back to    // LISTEN.    ACK(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort() &&       segment.getAcknowledgeNumber() == ctxt.getSequenceNumber()]        ESTABLISHED        {            accepted();            deleteSegment(segment);        }    Close        FIN_WAIT_1        {            doSend(TcpSegment::FIN,                   NULL,                   0,                   0,                   NULL);        }    AckTimeout        CLOSED        {            doSend(TcpSegment::RST,                   NULL,                   0,                   0,                   NULL);            closeSocket();        }}// A application-created client starts life in this state.SYN_SENTEntry{    startTimer("CONN_ACK_TIMER", TcpConnection::ACK_TIMEOUT);}Exit{    stopTimer("CONN_ACK_TIMER");}{    // When a TCP service accepts a new connection, it creates    // a new client to handle this connection.    SYN_ACK(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort() &&       segment.getAcknowledgeNumber() == ctxt.getSequenceNumber()]        ESTABLISHED        {            setFarAddress(segment);            sendSynAckAck(segment);            openSuccess();            deleteSegment(segment);        }    Close        CLOSED        {            closeSocket();            closed("");        }    ConnAckTimeout        CLOSED        {            closeSocket();            openFailed("acknowledge timeout");        }}ESTABLISHED{    FIN(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort()]        CLOSE_WAIT        {            doSend(TcpSegment::ACK,                   NULL,                   0,                   0,                   &segment);            halfClosed();            deleteSegment(segment);        }    PSH(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort()]        nil        {            doSend(TcpSegment::ACK,                   NULL,                   0,                   0,                   &segment);            receive(segment);            deleteSegment(segment);        }    Transmit(data: const char*, offset: int, size: int)        Transmitting        {            doSend(TcpSegment::PSH,                   data,                   offset,                   size,                   NULL);        }    Close        FIN_WAIT_1        {            doSend(TcpSegment::FIN,                   NULL,                   0,                   0,                   NULL);        }}TransmittingEntry{    startTimer("TRANS_ACK_TIMER",               TcpConnection::ACK_TIMEOUT);}Exit{    stopTimer("TRANS_ACK_TIMER");}{    ACK(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort() &&       segment.getAcknowledgeNumber() == ctxt.getSequenceNumber()]        ESTABLISHED        {            transmitted();            deleteSegment(segment);        }    PSH_ACK(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort() &&       segment.getAcknowledgeNumber() == ctxt.getSequenceNumber()]        ESTABLISHED        {            doSend(TcpSegment::ACK,                   NULL,                   0,                   0,                   &segment);            transmitted();            receive(segment);            deleteSegment(segment);        }    // If a push is received now, that means the far end sent    // data at exactly the same time as we sent it. Send an ack    // but don't go anywhere.    PSH(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort()]        nil        {            doSend(TcpSegment::ACK,                   NULL,                   0,                   0,                   &segment);            receive(segment);            deleteSegment(segment);        }    FIN(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort()]        CLOSE_WAIT        {            doSend(TcpSegment::ACK,                   NULL,                   0,                   0,                   &segment);            halfClosed();            deleteSegment(segment);        }    Close        FIN_WAIT_1        {            doSend(TcpSegment::FIN,                   NULL,                   0,                   0,                   NULL);        }    TransAckTimeout        CLOSED        {            transmitFailed("peer did not acknowledge");            closed("connection lost");        }}CLOSE_WAIT{    Close        LAST_ACK        {            doSend(TcpSegment::FIN,                   NULL,                   0,                   0,                   NULL);        }}LAST_ACKEntry{    startTimer("CLOSE_ACK_TIMER", TcpConnection::ACK_TIMEOUT);}Exit{    stopTimer("CLOSE_ACK_TIMER");}{    ACK(segment: const TcpSegment&)      [segment.getSrcAddress() == ctxt.getFarAddress() &&       segment.getSrcPort() == ctxt.getFarPort() &&       segment.getAcknowledgeNumber() == ctxt.getSequenceNumber()]        CLOSED        {            doSend(TcpSegment::FIN,                   NULL,                   0,                   0,                   &segment);            closeSocket();            closed("");            deleteSegment(segment);        }    CloseAckTimeout

⌨️ 快捷键说明

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