1
You can talk to octave directly from other environments over the tcp/ip.
2
The protocol is not sophisticated.
4
Here is what you can send to octave:
8
evaluate command in octave.
9
length is a 32-bit network order integer.
10
command is a string (without zero-terminator).
14
send matrix back to client.
15
length is a 32-bit network order integer.
16
name is a string (without zero-terminator).
18
I don't use the !!!m command to the server because it is the same as
20
!!!x send('name', matrix expression)
22
The latter is much more useful because you don't have to name
23
the data that you are sending across.
25
!!!n length namelen name command
27
*** Not implemented ***
28
Evaluate the command in the namespace. This needs a lookup table
29
Map<string,symbol_table> namespace
31
evalin(symbol_table,command)
32
The function evalin pushes the given symbol table onto curr_sym_tab,
33
evaluates the command then pops the symbol table.
35
Here is what you will receive from octave:
37
!!!m length rows columns namelength name data
39
recieve matrix from server.
40
length,rows,columns,namelength are 32-bit network order integers.
41
name is a string (without zero-terminator).
42
data is an array of rows*columns server order double values.
44
This is sent in response to a !!!m matrix request or a
45
send('name',matrix) command.
47
The first thing I do when I open a connection is request a matrix
48
containing 1.0. If the result is not 1.0, I know that I need to
49
swap the data to convert from server order to client order doubles.
51
!!!s length strlen namelen name str
53
receive string from server.
54
length, strlen, namelen are 32-bit network order integers.
55
name is a string (without zero-terminator).
56
str is a string (without zero-terminator).
58
This is sent in response to a send('name',string) command.
62
evaluate string in client.
63
length is a 32-bit network order integer.
64
str is a string (without zero-terminator).
66
This is sent in response to a send('str'). The contents of str
67
are completely arbitrary (and may indeed contain binary data). It is
68
up to the client to decide how they want to interpret these strings.
72
receive error from octave.
73
length is a 32-bit network order integer.
74
error is a string (without zero-terminator).
76
This is sent in response to a !!!x command which produced an error.
78
Composite values can be decomposed into their constituent parts. E.g.,
80
for [v,k]=x, send([name,'.',k],v); end
82
send([name,'.real'],real(x));
83
send([name,'.imag'],imag(x));
91
for r=1:nr, for c=1:nc, send([name,sprintf('.%d.%d',r,c)],x{r,c}); end
93
Note that the communication is completely asynchronous. I have a tcl client
94
that processes server responses via fileevent. That means that responses from
95
octave are not processed until tcl enters its event loop.
97
To be sure that octave has processed a command I follow that command with a
98
synchronization sequence:
100
set sync[incr syncid] 1
101
octave eval "send('unset sync$syncid')"
104
In practice it is more complicated than that because I allow the
105
syncronization command to time out just in case octave crashed out from
106
underneath me, but the idea is the same.
108
Using sockets gives you platform independence and network transparency,
109
which is a big win. The only caveat is that winsock is slow. The best I
110
can do with dedicated winsock code on my machine is .3 seconds to transfer
111
a 1 Mb message. Under tcl/tk, it was closer to 1 second IIRC. A memory
112
copy of the same size took less than 0.06 seconds IIRC.
114
That is why I'm working on a way to embed octave into tcl. Hopefully
115
it will be easy to embed in other environments as well.