Creating A Socket Connection in Flexsim
Creating A Socket Connection in Flexsim
FlexSim can be the server or the client. In this example, FlexSim is the server and the outside application
is the client.
The steps to communicate with FlexSim via sockets (and the corresponding FlexSim commands) are:
socketinit() – initializes a background process in Windows. This must be called before FlexSim can
even create a socket connection to send or receive messages. This function returns a True if the
initialization was successful.
servercreatemain(int port) – creates a socket that listens to the specified port. Some ports
are frequently used by Windows. These “well-known” ports should be avoided. Typically, anything over
1024 is safe to use.
This function returns an integer that serves as a unique identifier for this connection that should be
stored for later use. If a connection is not successful, a 0 is returned.
In C++ *buffer is a char pointer where the message will be stored and bufferSize limits how big a
message is stored. The return value is the number of bytes received.
serverclosemain() – closes the main server socket and all of the connections that are still open.
No more communication can be done until servercreatemain() is called again. All connections
should be closed individually (using servercloseeconnection()) before this is called.
Sample Model
Creating a Socket
In the sample model, in order to simplify socket creating and implement exception handling,
socketinit(), servercreatemain(), and serveraccept() are in the startSocket user
command.
Note: serverclosemain() is called if the connection was not successful. This is probably not be the
best approach to exception handling because all open connections should be closed (using
servercloseconnection()) before calling serverclosemain(). If an individual connection is
not closed before calling serverclosemain(), weird things happened with sockets that could only
be fixed by closing and reopening FlexSim.
We made the assumption that only one socket connection would be made in this model and since the
connection was not successful, we could close the main connection here.
startSocket();
createview("MAIN:/project/model/Tools/TimerObj");
TimerObj is actually a view and is located in the Tools node. When the view is created, the OnOpen node
executes the following:
applicationcommand("settimer", c, 100);
which starts the timer and executes the OnTimerEvent in 100 miliseconds. The OnTimerEvent will
continue to execute every specified number of milliseconds as defined in the time variable. The timer
execute until the OnClose node executes the following:
applicationcommand("killtimer", c);
The variable message will contain the text received via the connection defined by the first parameter
(getnodenum(node("/Tools/client", model())). Since this will be executed many times a second,
most of the time message will be blank. So we must check to see when a message was received:
if(!comparetext(message,""))
{
//do something with message
serversend(getnodenum(node("/Tools/client", model())), "ask");
}
The last line is not necessary. It is just an acknowledgment sent back to the client so it knows the
message was received. This needs to happen only if the client requires it.
After all messages have been received, it is important to close the socket connection(s). The sample
model uses a user command called endSocket() to execute the following:
servercloseconnection(getnodenum(node("\Tools\client", model())));
serverclosemain();
socketend();
Notice the first parameter in servercloseconnection() is the reference to the connection identifier
created and stored when the socket connection was created. In the sample model, endSocket() is
executed in the OnClose of the TimerObj.