# Delay in TCP/IP communication

**URL:** <https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [January 28, 2025, 2:15am UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463 "2025-01-28T02:15:47Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 2:15am UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/1 "2025-01-28T02:15:47Z")

</div>

Hello,

As a forewarning: I am new to Python programming and very inexperienced with programming in general, which includes Ignition.

I am attempting to create a crude program to test the validity of communicating with a small robot arm over TCP/IP. I have successfully sent and received data, but there is a delay of approximately 20-30 seconds between my button press (triggering my script) and action from the robot arm and a flurry of received data. I have tested TCP/IP communication with PuTTY, and that is immediate, while a separate Python program I wrote (very basic) has almost no delay after I enter something in the command line.

I have seen in other posts here that importing Python libraries to manage TCP/IP socket communication is not advised, which is what I am doing\*. Is this the reason for the large delays? I spoke with a coworker and they suggested I first try sustaining a socket rather than opening one, sending/receiving data, and then closing it for every unique command. I'm hoping someone here might know the more likely culprit for the delays.

The send data is something like "ActivateRobot", "GetCheckpoint", or "StartProgram(##)" while the received data is [####][##] or [####][Connected to robot R## v##.##]

\*I made an attempt to convert the python to java but ran into formatting issues.  
The send and receive data is relatively small.

Thank you for your time!

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [January 28, 2025, 4:07am UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/2 "2025-01-28T04:07:24Z")

</div>

You'll need to share your code to get some feedback.

I think it's likely that at least some of your problem is that by doing this in a button press you're executing blocking code on the UI thread, and your UI freezes until it finishes. But we'll need code to help you.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 5:18pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/3 "2025-01-28T17:18:14Z")

</div>

Hmm, I am writing the responses from the robot to a memory tag using `system.tag.writeBlocking()`. Something else I found in my searches through the posts here. I'm writing the responses to a memory tag so that I can see them in a separate text box. That is the idea anyway.

I'm going to try `system.tag.write()` (just looked it up, should have done so before) and see where I get from there. I will respond with my progress.

The buttons are not mandatory. I just need a way to store the responses so that I know, should we have a professional program this in the future, they can receive a confirmation from the robot that indicates the robot finished a particular work cycle. The display of the response is just for my QOL and debugging.

First button.

```python
import sys
import socket
import time

#create an INET, STREAMing socket (IPv4, TCP, TCP/IP)
try: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
	SocketMsg = 'Failed to create socket'
	system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg]) #writing to memory tag value
	sys.exit()

SocketMsg = 'Socket created'
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])

RobotIP = "IP_number"
RobotPort = 10000
#Connect the socket object to the robot using the IP address (string) and port (int)
client.connect((RobotIP,RobotPort))

SocketMsg = 'Socket connected to ' + RobotIP
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])
#Read the response sent by the robot upon connecting
SocketMsg = client.recv(1024).decode('ascii')
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])

client.close()
sys.exit()

```

second button:

```python
import sys
import socket
import time

#create an INET, STREAMing socket (IPv4, TCP, TCP/IP)
try: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
	SocketMsg = 'Failed to create socket'
	system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])
	sys.exit()
	
SocketMsg = 'Socket created'
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])

RobotIP = "192.168.0.42"
RobotPort = 10000
#Connect the socket object to the robot using the IP address (string) and port (int)
client.connect((RobotIP,RobotPort))

SocketMsg = ('Socket connected' + RobotIP)
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])
#Read the response sent by the robot upon connecting
SocketMsg = client.recv(1024).decode('ascii')
system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])

#send command to activate the robot
cmd = 'ActivateRobot'
#add ASCII NULL character at the end of the command string
try:
	client.send(bytes(cmd+'\0' + 'ascii'))
	time.sleep(15)
	SocketMsg = client.recv(1024).decode('ascii')
	system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])
except socket.error:
	SocketMsg = 'Failed to send data'
	system.tag.writeBlocking(["[default]Meca500_TCP/SocketMsg.value"],[SocketMsg])

client.close()
sys.exit()

```

Thanks!

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [January 28, 2025, 5:40pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/4 "2025-01-28T17:40:18Z")

</div>

> [@C\_B](#):
>
> I'm going to try `system.tag.write()`

Use `system.tag.writeAsync` instead, `system.tag.write` is deprecated.

> [@C\_B](#):
>
> `sys.exit()`

Don't ever use `sys.exit()` in Ignition.

Define these button scripts as functions in the top level scripting library for the project. Then instead of `sys.exit()` use `return`. Call these functions in the relevant button action scripts.

Consider using a logger for the basic 'Robot connected', 'robot connection failed', etc messages, and only write the actual robot response to the tag. Loggers show up in the bottom of the designer by default, and you can open a menu to see the logs in a vision client.

How fast are you planning on talking to this robot? You might be able to get away with making it a TCP device on your gateway.

For a quick 'Fire and forget' command method, just to see if you can get the robot to start quickly without looking for a response:

```python
from java.net import Socket
from java.io import DataOutputStream
from java.lang import Throwable

logger = system.util.getLogger("RobotConnectionProject." + __name__ )

def sendRobotCommandViaSocket(command, robotIP, robotPort):
	if not robotIP:
		logger.warn("Unable to send command to robot, robot IP not specified")
		return False

	if not robotPort:
		logger.warn("Unable to send command to robot, robot port not specified")
		return False

	try:
		robotSocket = Socket(robotIP, robotPort)
		robotOutputStream = DataOutputStream(robotSocket.getOutputStream())
		robotOutputStream.write(command)

		robotOutputStream.close();
		robotSocket.close();

	except Throwable as t:
		logger.warn("Java error while attempting to send robot command via socket", t)
		return False

	except Exception as e:
		logger.warn("Jython error while attempting to send robot command via socket")
		return False

	return True

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [January 28, 2025, 5:43pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/5 "2025-01-28T17:43:32Z")

</div>

> [@C\_B](#):
>
> `SocketMsg = client.recv(1024).decode('ascii')`

> [@C\_B](#):
>
> ```python
> time.sleep(15)
> SocketMsg = client.recv(1024).decode('ascii')
> 
> ```

Lines like these are going to freeze your UI. The sleep is especially bad because your UI will freeze for 15 seconds every time on that line.

You should get a packet capture with Wireshark. See if there's any delay between your button press and the request being sent, and between the request and response.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 6:01pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/6 "2025-01-28T18:01:51Z")

</div>

Hello Ryan,

I am running into difficulties with `system.tag.write()` right now, so thank you for the tip about it being deprecated. I scrolled down past the big yellow header saying so in my race to use it.

Thank you for the notice about sys.exit(). Not in my defense of myself or to throw someone else under the bus, but nearly all of this came from the robot API example, which was specifically written for Python. I figured it wasn't going to be ideal, but it was a starting point.

Both robot ports are already on the TCP gateway. I can see their responses when I enable them on the gateway. However, when I enable them on the gateway, the robot refuses any new socket connections as it only supports one. I looked up joining into a socket, but that it far and above my skill level.

As far as communication rates, each robot subroutine takes a few seconds, so if we can stay ahead of that then we're good. We use PLCs a lot, so we're familiar with 100-200 millisecond scan times (not that we utilize those rates, mind you). If sending messages and expecting responses in the neighborhood of once a second or less is untenable, then we will probably stick with PLCs.

And thank you for the code example, I appreciate that!

Hello Kevin,

15 seconds?! I figured it was milliseconds since that makes for easy integers.

Maybe I am not understanding the forum formatting completely, but I am surprised that `SocketMsg = client.recv(1024).decode('ascii')` would cause a delay. That is required to set the maximum message size and how it is to be encoded, correct?

I have wireshark and have used it before - I will utilize it here.

Thank you for your input, I appreciate it.

---

<div class="post-metadata">

**Author:** ![dillon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dillon/32/81537_2.png) [@dillon](https://forum.inductiveautomation.com/u/dillon)\
**Post date:** [January 28, 2025, 6:04pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/7 "2025-01-28T18:04:34Z")

</div>

> [@C\_B](#):
>
> 15 seconds?! I figured it was milliseconds since that makes for easy integers.

Welcome to programming in Python 🙂

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [January 28, 2025, 6:05pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/8 "2025-01-28T18:05:49Z")

</div>

> [@C\_B](#):
>
> 15 seconds?! I figured it was milliseconds since that makes for easy integers.

[https://docs.python.org/2.7/library/time.html#time.sleep](https://docs.python.org/2.7/library/time.html#time.sleep)

> [@C\_B](#):
>
> Maybe I am not understanding the forum formatting completely, but I am surprised that `SocketMsg = client.recv(1024).decode('ascii')` would cause a delay.

I should say... it _can_ block. It will block until at least one byte is received. It will return at most 1024 bytes the way you're calling it.

But there's no guarantee about how many bytes are returned; it returns as many as are available. That could be 1, 2, 20, or all of them. TCP is a streaming protocol, and data sent via TCP typically has to be framed in some manner so that the receiving side knows when it's received the entire message.

I suspect that may be why you were messing around with a sleep call...

[https://docs.python.org/2.7/library/socket.html#socket.socket.recv](https://docs.python.org/2.7/library/socket.html#socket.socket.recv)

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 6:16pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/9 "2025-01-28T18:16:06Z")

</div>

Ah ok, the blocking until something is received makes sense.

Not to defend my poor programming, but the sleep call was part of the example TCP/IP program from the robot manufacturer. I started with some of the examples in prior forum posts here but was unable to adapt them to my needs, and then started looking to see if the manufacturer had anything. It does make sense why they would start there though, that way they ensure you receive a message when you're just testing. Later when you run into time delay issues you start a forum post for a different product because surely the issue lies there.

Thank you for all of the resources, I will try to to implement them and improve my attempts.

---

<div class="post-metadata">

**Author:** ![dillon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dillon/32/81537_2.png) [@dillon](https://forum.inductiveautomation.com/u/dillon)\
**Post date:** [January 28, 2025, 6:17pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/10 "2025-01-28T18:17:00Z")

</div>

> [@C\_B](#):
>
> Not to defend my poor programming, but the sleep call was part of the example TCP/IP program from the robot manufacturer.

They most likely didn't take into account that doing this hangs up the same thread that manages the UI of the Perspective session (edge case). In most cases it would probably be ok.

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [January 28, 2025, 6:40pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/11 "2025-01-28T18:40:47Z")

</div>

> [@C\_B](#):
>
> Both robot ports are already on the TCP gateway. I can see their responses when I enable them on the gateway. However, when I enable them on the gateway, the robot refuses any new socket connections as it only supports one.

You should be able to configure them to also allow writes, and send your commands via that tag.

> **[UDP and TCP Driver | Ignition User Manual](https://www.docs.inductiveautomation.com/docs/8.1/ignition-modules/opc-ua/opc-ua-drivers/udp-and-tcp-driver#advanced)**
>
> Ignition's UDP and TCP drivers allows Ignition to communicate to various devices like barcode scanners, and scales. These are not catch-all drivers that will talk to any PLC that communicates over TCP, but rather very basic drivers that will...

> [@C\_B](#):
>
> will probably stick with PLCs.

Are you trying to drive the steps of your process using Ignition instead of something like PLC at the station?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [January 28, 2025, 6:44pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/12 "2025-01-28T18:44:44Z")

</div>

I don't think the TCP driver is going to be a good fit for this. It sounds like the response messages are going to be too variable.

It's really only a good option when you are talking to something like a barcode scanner or scale that is going to spit out very regular fixed-length or delimited messages.

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [January 28, 2025, 6:46pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/13 "2025-01-28T18:46:54Z")

</div>

> [@Kevin.Herron](#):
>
> I don't think the TCP driver is going to be a good fit for this.

I kind of figured, but was hopeful that they would not need to get into long lived socket threads.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 7:27pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/14 "2025-01-28T19:27:39Z")

</div>

I will review the gateway port communication to see if I can adjust them appropriately.

We have already established a working process with a PLC (the PLC calls stored subroutines on the robot memory), but we wanted to see if we could bypass all logic on the PLC and use it as an I/O rack while Ignition does the thinking. We have encountered some customers who prefer this method so we like to explore this option when possible.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 7:33pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/15 "2025-01-28T19:33:13Z")

</div>

For the most part it is regular, typically [####][##]. The welcome message is a longer string though. But, this exercise was to find out these issues specifically and determine how appropriate Ignition (at least TCP/IP communication) might be in this situation. I will explore some of the options and tips mentioned above though to see how close they might get me.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 28, 2025, 7:51pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/16 "2025-01-28T19:51:50Z")

</div>

If you have larger hopes for this communication than just a few tests, you will need to re-architect the whole thing. As Kevin alludes above, you simply cannot do blocking (sleeping or waiting) operations in a Vision Client event.

You will likely need to study the topics here that describe what is needed to run long-lived threads (if you absolutely must use linear code), or learn to use timer events to run short chunks of code in a state machine.

A machine manufacturer chunk of standalone sample code is not transferable to Ignition's event-driven code model.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 8:21pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/17 "2025-01-28T20:21:26Z")

</div>

This is absolutely just for a few tests. We have others who are better versed with software here, and when we need serious solutions, we contract with a team of of dedicated software engineers.

I am in the process of studying all of the responses here as it not only helps with this task but helps in the future.

I didn't mean to imply that the sample code from the manufacturer would be sufficient for an actual solution. I read through a number of TCP/IP posts here (a number of them featuring your responses, including not using `import socket`) and tried to adapt the solutions proffered there but was unable to get them working due to my lack of knowledge. Fortunately for me, and unfortunately for everyone here, the sample code at least got me responses from the robot, so it was/is my starting point.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [January 28, 2025, 8:29pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/18 "2025-01-28T20:29:41Z")

</div>

If you had a manual or documentation or could otherwise accurately describe the response message format you might get a few more hints from people.

---

<div class="post-metadata">

**Author:** ![C\_B](https://avatars.discourse-cdn.com/v4/letter/c/d78d45/32.png) [@C\_B](https://forum.inductiveautomation.com/u/C_B)\
**Post date:** [January 28, 2025, 8:49pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/19 "2025-01-28T20:49:22Z")

</div>

Before I take up more of everyone's time here, I will work on the suggestions people have posted here as well as what my own research turns up. The intent with my original post was not to co-opt everyone's time here to solve my issue, but to see if my timing issues were more likely to be python related or opening/closing socket related so that I could then pick the most probable path to research. Looking back, I see I could have been more clear in that.

However, I would like to stress that I greatly appreciate everyone's help and input on this matter.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 28, 2025, 9:06pm UTC](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463/20 "2025-01-28T21:06:37Z")

</div>

> [@C\_B](#):
>
> co-opt everyone's time here

No worries. We're a bunch of nerds here. 😁

[Next page](https://forum.inductiveautomation.com/t/delay-in-tcp-ip-communication/101463.md?page=2)
