📄 tcpconnection.java
字号:
//// 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.java//// Description// Both TCP client and server sockets are TCP connections.//// RCS ID// $Id: TcpConnection.java,v 1.7 2007/12/28 12:34:40 cwrapp Exp $//// CHANGE LOG// $Log: TcpConnection.java,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:51:24 cwrapp// Update Java examples 1 - 7.//// Revision 1.0 2003/12/14 20:19:31 charlesr// Initial revision//package smc_ex6;import java.io.IOException;import java.lang.reflect.Method;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public abstract class TcpConnection implements DatagramSocketListener, TimerListener{//---------------------------------------------------------------// Member methods.// public final void close() { synchronized (this) { try { // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); _fsm.Close(); // Wait for the connection to close before // returning. while (_async_socket != null) { try { this.wait(); } catch (InterruptedException interrupt) {} } } finally { this.notify(); } } return; } public final void handleReceive(DatagramPacket packet, AsyncDatagramSocket dgram_socket) { synchronized (this) { try { TcpSegment segment = new TcpSegment(packet); Object[] args = new Object[1]; // Generate the appropriate transition based on // the header flags. args[0] = segment; // DEBUG// System.out.println(// "Receive event from " +// packet.getAddress() +// ":" +// Integer.toString(packet.getPort()) +// ":\n" +// segment); // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); _transition_table[segment.getFlags()].invoke( _fsm, args); } catch (Exception jex) { System.err.println(jex); jex.printStackTrace(); } finally { this.notify(); } } return; } public final void handleError(Exception e, AsyncDatagramSocket dgram_socket) { // TODO // Generate the appropriate transition. } public final void handleTimeout(String name) { synchronized (this) { try { // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); if (name.compareTo("CONN_ACK_TIMER") == 0) { _fsm.ConnAckTimeout(); } else if (name.compareTo("TRANS_ACK_TIMER") == 0) { _fsm.TransAckTimeout(); } else if (name.compareTo("CLOSE_ACK_TIMER") == 0) { _fsm.CloseAckTimeout(); } else if (name.compareTo("CLOSE_TIMER") == 0) { _fsm.CloseTimeout(); } else if (name.compareTo("SERVER_OPENED") == 0) { _fsm.Opened(); } else if (name.compareTo("CLIENT_OPENED") == 0) { _fsm.Opened(_address, _port); } else if (name.compareTo("OPEN_FAILED") == 0) { _fsm.OpenFailed(_errorMessage); _errorMessage = null; } } finally { this.notify(); } } return; } // Server socket constructor. protected TcpConnection(TcpConnectionListener listener) { _listener = listener; _fsm = new TcpConnectionContext(this); _sequence_number = 0; _async_socket = null; _address = null; _port = -1; _server = null; _errorMessage = null; // REFLECTION // Turn on FSM debugging. // _fsm.setDebugFlag(true); return; } // "Accepted" socket constructor. protected TcpConnection(InetAddress address, int port, DatagramSocket socket, int sequence_number, TcpServer server, TcpConnectionListener listener) { _async_socket = new AsyncDatagramSocket(socket, this); _address = address; _port = port; _sequence_number = sequence_number; _server = server; _errorMessage = null; _listener = listener; _fsm = new TcpConnectionContext(this); // REFLECTION // Turn on FSM debugging. // _fsm.setDebugFlag(true); _async_socket.start(); return; } protected final void passiveOpen(int port) { synchronized (this) { try { // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); _fsm.PassiveOpen(port); } finally { this.notify(); } } return; } protected final void activeOpen(InetAddress address, int port) { synchronized (this) { try { // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); _fsm.ActiveOpen(address, port); } finally { this.notify(); } } return; } protected final void acceptOpen(TcpSegment segment) { synchronized (this) { try { // REFLECTION // Uncomment the following line to output // transitions. // _outputTransitions(); _fsm.AcceptOpen(segment); } finally { this.notify(); } } return; } protected final void setListener(TcpConnectionListener listener) throws IllegalStateException { if (_listener != null) { throw( new IllegalStateException( "Socket listener already set")); } else { _listener = listener; } return; } protected void transmit(byte[] data, int offset, int length) { synchronized (this) { try { // REFLECTION // Uncomment the following lines to output // transitions. // _outputTransitions(); _fsm.Transmit(data, offset, length); } finally { this.notify(); } } return; } //----------------------------------------------------------- // State Map Actions. // /* package */ InetAddress getFarAddress() { return (_address); } /* package */ int getFarPort() { return (_port); } /* package */ int getSequenceNumber() { return (_sequence_number); } /* package */ void openServerSocket(int port) { DatagramSocket socket; try { // Create the asynchronous datagram socket listener and // start it running. socket = new DatagramSocket(port); _async_socket = new AsyncDatagramSocket(socket, this); _async_socket.start(); // Set the sequence number. _sequence_number = ISN; startTimer("SERVER_OPENED", MIN_TIMEOUT); } catch (Exception jex) { _errorMessage = jex.getMessage(); startTimer("OPEN_FAILED", MIN_TIMEOUT); } return; } /* package */ void openClientSocket(InetAddress address, int port) { DatagramSocket socket; try { socket = new DatagramSocket(); _address = address; _port = port; _async_socket = new AsyncDatagramSocket(socket, this); _async_socket.start(); // Set the sequence number. _sequence_number = ISN; startTimer("CLIENT_OPENED", MIN_TIMEOUT); } catch (Exception jex) { // Do not issue a transition now since we are already // in a transition. Set a 1 millisecond timer and // issue transition when timer expires. _errorMessage = jex.toString(); startTimer("OPEN_FAILED", MIN_TIMEOUT); } return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -