Code covered by the BSD License  

Highlights from
TCP/IP Communications in Matlab

4.91667

4.9 | 12 ratings Rate this file 189 Downloads (last 30 days) File Size: 12.79 KB File ID: #24524

TCP/IP Communications in Matlab

by Kevin Bartlett

 

22 Jun 2009 (Updated 03 Feb 2012)

Sends/receives TCP packets using Matlab's Java interface. Now handles matrices and cell arrays, etc.

| Watch this File

File Information
Description

Transmission Control Protocol (TCP/IP) communications are used to send data from one computer to another over a network or from one application to another within a single computer.

The jtcp.m program uses Matlab's ability to call Java code to enable it to send and/or receive TCP packets. One Matlab session can communicate with another Matlab session (on the same machine or over the network) or it can communicate with a completely different program (again, on the same machine or over the network).

This latest version of jtcp.m uses Java's serialization functionality to write and read strings, matrices, cell arrays and primitives (that is, just about any Matlab variable type other than structures).

Serialization will cause errors if jtcp.m is talking to a program or piece of hardware that does not itself implement serialization. In this case, set the 'serialize' argument to false when requesting or accepting a connection. This will limit read and write operations to variables of type "int8", which most socket applications will be able to handle.

Required Products MATLAB
MATLAB release MATLAB 7.8 (R2009a)
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (38)
29 Jun 2009 Jayson Brouchoud

Kevin,

This tool has been extremely useful for me. There is one problem I haven't gotten around yet. I'm regularily checking to see if other PCs have "logged on" so I'm doing a jtcp('accept') command triggered off a timer. The problem is that if the PC is not logging on, then I get a timeout as expected, but it hangs the port. I added a try/catch, but this kicks the jtcp routine back before it closes the port so I have the same problem. I'm sure it's my lack of how to use the tool properly, but if you have any suggestions, I would appreciate them.

Thanks,
Jayson

29 Jun 2009 Kevin Bartlett

Hi Jayson,

No, it wasn't your fault; I failed to close the server socket in the event of a timeout. I've posted an updated version that I hope fixes the problem, but it hasn't appeared online yet. Look for an "Updates" section to appear in the next day or so below this "Comments and Ratings" section and then download the new version.

Glad you're finding it useful! And thanks for your help!

Kevin.

23 Sep 2009 Derek Eggiman

Very nice example. However I've noticed your read function could be improved or perhaps cleaned up a little. Instead of the while loop for timeout you could do the following.

import java.net.Socket
import java.net.InetSocketAddress
            
%Set SocketAddress
sAddress = InetSocketAddress(Host,Port);
            
%Establish unconnected socket.
socket = Socket();

%connect
try
socket.connect(sAddress,timeout);
end

02 Nov 2009 Wei Ren

Can the output be anything else besides char? like hexidecimal for example?

09 Nov 2009 Edwin Carter

Great little example.
The only problem I've found is that binary numbers >127 get mapped to zero on read. I found that replacing
mssg(i) = jTcpObj.dataInputStream.readByte;
with
mssg(i) = read( jTcpObj.dataInputStream );
(in jtcp_read(), line 396)
solves this issue, but I don't know if this is the right thing to do...

09 Nov 2009 Kevin Bartlett

Edwin, changing line 396 to
   "mssg(i) = read( jTcpObj.dataInputStream );"
might well be the right thing to do, but I can't say for sure that this won't cause more problems.

When I wrote jtcp.m, I limited it to handling strings because I don't really understand the internal workings of Sockets very well. Making it handle binary, hex, etc., seemed overly ambitious. I figured that for most applications the user could convert data to strings on one end and back to the original format (e.g., binary or hex) on the other.

I originally had a line testing to see if the user had entered a value of mssg that was not a string, but for some reason I commented it out. I have re-enabled this line, so now a non-string message will raise an error. Anybody who really wants to use jtcp.m to transmit binary or hex will have to re-comment out this test.

If there are any Sockets experts out there who want to take on the challenge of enhancing jtcp.m to handle other data types, I would encourage them to copy my code, build an improved version and post it to the File Exchange themselves, since this sort of thing is well outside my area of expertise.

Wei Ren, I hope this answers your question as well.

09 Nov 2009 Wei Ren

Hey thanks for the reply.
I'll try to see what matlab can do with changing the formats correctly how I need it. This is going to take some trial and error.

I wish it was more well documented.

09 Nov 2009 Kevin Bartlett

Hexadecimal should be easy, since (as I understand it) Matlab stores hexadecimal numbers as strings anyway. If you have a decimal number to send, you can convert it to a string with sprintf or num2str. You can also switch back and forth from hex to decimal with hex2dec and dec2hex.

09 Nov 2009 Wei Ren

The thing is that I need my server to communicate to an application that will need it in HEX. so :(

13 Nov 2009 Wei Ren

so according to wireshark
mssg = sscanf(' 02 04 05 B4 01 01 04 02','%x');
using either
jTcpObj.dataOutputStream.writeBytes(char(mssg));
or
jTcpObj.dataOutputStream.write(mssg);
show as 02 04 05 B4 01 01 04 02 sent correctly. which is what I want.

also have you tried
 data_reader = DataReader(d_input_stream);
message = data_reader.readBuffer(bytes_available);
Rodney had that new in his 2nd update of his syntax.
I tried adding that to your script but couldnt get it to work right.

13 Nov 2009 Wei Ren

I forgot to note that even though it's sent correctly through wireshark, im still unable to read it correctly yet on matlab.
any ideas on how 0xB4 becomes -74?

13 Nov 2009 Kevin Bartlett

@Wei Ren: I saw Rodney's new DataReader class. I might try to incorporate it into jtcp to make it more efficient, but I haven't gotten around to it yet.

Regarding sending/receiving hex data: sorry, no clue. I'll keep playing with jtcp to see if it can be expanded to data types other than strings. If you figure anything out in the meantime, please let me know.

15 Nov 2009 Wei Ren

so using mssg(i) = read( jTcpObj.dataInputStream ) actually solved the problem of why 0xB4 was becoming -74. (Thanks Edwin)

So this is what i do sending hex data
mssg = sscanf(' 02 04 05 B4 01 01 04 02','%x');
jTcpObj.dataOutputStream.write(mssg);
jTcpObj.dataOutputStream.flush;

jTcpObj.dataOutputStream.writeBytes(mssg) works as well and both would work without using the flush class too.

on the receiving end
convert the mssg to hex using dec2hex(mssg)

15 Nov 2009 Matthias Geier

Hi Kevin and others.

I had a similar problem when I wanted to send strings which contained binary zeros (\0) as separators.
This didn't work with writeBytes() because the binary zero was interpreted as end-of-string.
Also, when I analyzed the IP traffic with wireshark, I saw that sometimes (strangely not always) an IP packet was sent for every single character of my message-string, which seemed quite inefficient to me.

So I changed line 351 from

jTcpObj.dataOutputStream.writeBytes(char(mssg));

to

jTcpObj.dataOutputStream.write(uint8(mssg), 0, length(mssg));

... where the second argument is an offset (which I chose to be 0).

This worked perfectly for me, I think it could also work for others, but of course I'm not sure about any side-effects or pitfalls ...

BTW, I didn't didn't care about receiving data, because I used another application for that.

Thanks for the this great m-file, it was very useful!

16 Nov 2009 Kevin Bartlett

@Matthias and Rei Wen: I think we may be running into some platform-dependent stuff (I'm running Linux). I never had the problem in which 0xB4 becomes -74, and binary zeroes were coming through fine. I've rewritten jtcp.m to send messages in int8 format, rather than as strings. I'm hoping this will result in less variability in its behaviour. I also took Matthias' suggestion of using write() instead of writeBytes(). I'd appreciate you letting me know how this works for you.

In addition, I have incorporated Rodney Thomson's DataReader java class into the program (its use is optional). Again, let me know how this works for you.

16 Nov 2009 Wei Ren

Kevin: I just wanted to make sure that you didn't misunderstood what i said last. 0xB4 is 180 in decimal. I was getting -74 until I corrected what Edwin pointed out.

17 Nov 2009 Kevin Bartlett

@Wei Ren: Thanks for the feedback. I don't think I misunderstood you. You were finding that when you sent 0xB4 (decimal 180), you were receiving -74; you found that Edwin's fix of using
   mssg(i) = read( jTcpObj.dataInputStream );
instead of
   mssg(i) = jTcpObj.dataInputStream.readByte;
solved this problem.

However my point is that I never experienced this same problem using readByte(), which is why I think there may be some platform-dependent issues here.

I think that switching from transmitting chars to transmitting int8 values, as I've done in the newest version, ought to avoid some of these issues.

Let me know how it works for you and if any of the same problems crop up again.

18 Nov 2009 Matthias Geier

@Kevin: Thanks for your response and for the adaptation of your code!
Just for the records: I was also running Matlab on Linux and I did have problems sending binary zeros.
I didn't try it on other operating systems.
I didn't try other strange characters either, just binary zeros and plain ASCII letters and punctuation.

24 Aug 2010 Tanyer Alan  
14 Oct 2010 Timothy

I'm looking at MATLAB (+ Add ons as requried) as part of my dissertaion to model SCADA vulnerabilities, when they use TCP/IP (UDP) etc. This has popped up in my searching. Anybody any ideas if this file is suitable?

13 Nov 2010 Elham Dolatabadi

Hello Kevin,

I tried to run the code and start a request from client to server but I got this error;
"??? Java exception occurred:
java.lang.IllegalArgumentException: timeout < 0

at java.net.PlainSocketImpl.setOption(Unknown Source)

at java.net.ServerSocket.setSoTimeout(Unknown Source)

Error in ==> jtcp>jtcp_accept_connection at 345
serverSocket.setSoTimeout(timeout);

Error in ==> jtcp at 256
    jTcpObj = jtcp_accept_connection(port,timeout);"

What does that mean?

19 Jan 2011 Kotya Karapetyan

Hello,

I am trying to use this tool to control a GPIB device over Ethernet using a Prologix' GPIB-Ethernet controller. Somehow I fail so far.

E.g., this controller can accept the command '++addr' and return the address of the device it is controlling. With a terminal program (I am using PuTTY), I type in '++addr' and get '5' in return. I am trying the code:

JTCPOBJ = jtcp('REQUEST', '131.220.157.23', 1234)
jtcp('WRITE',JTCPOBJ,int8('++addr'))
mssg = jtcp('READ', JTCPOBJ)

in the hope to see the response, but get a 1-by-0 matrix in response. Can you see what I am doing wrong? The IP address and the port are exactly the same as with the terminal.

19 Jan 2011 Kotya Karapetyan

I've found the problem: I was submitting int8('++addr'), but I should have submitted [int8('++addr') 13 10] to imitate CR.

22 Mar 2011 Alan

Thanks. Very nice.

28 Jun 2011 Ian

I'd love to be able to use this to send / receive class objects too. The way PNET does this is serialize an object to file (save it), then send the bytes, saved to file on the remote end and loaded back in. This is not efficient, but until TMW allows us to serialize objects properly, this works well enough.

26 Jul 2011 Patrick Damiani

Kevin,

I just downloaded your code, but I haven't had a chance to run it yet. I noticed in the description, you specifically say that it does not work on structures. Do you have plans to update this to send and receive structures?

26 Jul 2011 Kevin Bartlett

Hi Patrick. No, no plans to accommodate structures. You can easily pass any particular structure type by writing encode/decode functions to loop over the fields, passing each one to jtcp.m and re-assembling the structure on the other side. To make jtcp.m send and receive arbitrary structures, however, would require recursive programming to handle multiply-nested structures of all possible data types, and I didn't want to go that route.

27 Jul 2011 Jesse Hopkins

Patrick and Ian, take a look at CompressLib on the file exchange. Using this you can serialize almost any matlab structure to an array of bytes, and deserialize it back to a matlab structure on the other side. You can do classes as well, although that takes some work in the class definition itself.

27 Jul 2011 Patrick Damiani

Kevin, I was planning as much, but then I was going to ask if you knew if it was possible to... do exactly what Jesse has suggested. Thank you Jesse. I will check out CompressLib and see if the combination works for what I need.

27 Jul 2011 Patrick Damiani

Hey Jesse, I looked up and down the file exchange for something called CompressLib. I tried searches for: convert, compress, structures, binary, tcp, bytes, variables, and the like. Is CompressLib still on the exchange?

27 Jul 2011 Jesse Hopkins

Here's a link to CompressLib: http://www.mathworks.com/matlabcentral/fileexchange/25656-compression-routines

22 Aug 2011 Nor Muzakkir

i cant connect at all. i've tried adding Rules in the firewall (even tried when turning off the firewall) but still i keep failing to make connection.

i really dont understand much on networking procedures, but if anyone could help point out the steps to make this works (especially establishing connection) it would be very helpful.

Thanks so much.

22 Aug 2011 Kevin Bartlett

Hi Nor, are you connecting two Matlab sessions together or trying to connect Matlab with some other software? Are you on Windows? Mac? Linux? What error message do you get when you fail to make a connection?

Probably the easiest way to play with jtcp.m is to get two Matlab sessions running on one computer (assuming your licence permits it). Assign one session the role of "client" and the other the role of "server and follow the example code in jtcp.m's help, with "client" lines being executed in the client session and the "server" lines being executed in the server session. EXECUTE THE LINES IN THE ORDER SHOWN IN THE HELP EXAMPLES. You can substitute a higher value than 2000 milliseconds for the timeout, if that makes things easier. I have used port 21566 in the examples; this port will have to be open in your firewall, or the firewall turned off.
Kevin.

12 Sep 2011 Mr Smart  
04 Oct 2011 Musharaf Ali

Excellent ,I works great and easy to use ,Bless you

08 Nov 2011 Dean Kleissas  
05 Dec 2011 Alexander Kosenkov  
20 Jan 2012 Ueli Rutishauser  
Please login to add a comment or rating.
Updates
29 Jun 2009

Call to serverSocket.close added in try/catch statement in order to fix bug, spotted by Jayson Brouchoud, that caused port to hang after an "accept" timed out.

05 Oct 2009

Implemented suggestion from Derek Eggiman to replace while loop with built-in java socket timeout feature.

09 Nov 2009

Enabled call to error() if user inputs a value of mssg that is not a string.

16 Nov 2009

Switched to sending/receiving messages of "int8" format, rather than strings. Enabled optional use of Rodney Thomson's DataReader java class for more efficient reading of incoming data.

27 Jun 2011

Re-wrote Java code to permit reading and writing of cell arrays, matrices, strings, etc. (previous version limited to type "int8").

19 Jan 2012

Incorporates code from the earlier, int8-only version of jtcp.m to make data serialization optional. This allows jtcp.m to communicate with programs/hardware that do not themselves implement serialization.

03 Feb 2012

Removed reference to older version of jtcp.m (no longer included in zip file) from description.

Tag Activity for this File
Tag Applied By Date/Time
communications Kevin Bartlett 23 Jun 2009 12:27:43
network Kevin Bartlett 23 Jun 2009 12:27:43
tcpip Kevin Bartlett 23 Jun 2009 12:27:43
tcp Kevin Bartlett 06 Oct 2009 09:41:17
communications chris Hallgren 13 Nov 2009 09:01:20
tcp SAGAR 08 Mar 2010 09:39:33
tcp Yugandhar Valluru 27 May 2010 08:59:13
tcp Ariel Loyarte 10 Sep 2010 16:21:51
communications Raffaele 11 Oct 2010 09:21:31
communications milad 06 Jan 2011 08:15:20
network milad 06 Jan 2011 08:15:26
tcp milad 06 Jan 2011 08:15:28
socket Ueli Rutishauser 20 Jan 2012 11:21:52

Contact us at files@mathworks.com