Mariangela Camarda

TCP SOCKET NEEDS TO CLOSE and REOPEN FOR EACH MESSAGE

20 posts in this topic

Good Morning,

I connect using a TCPSocket a remote node with my NJ501-1300. In order to test communication with the remote node I use a telnet communication and send from it messages to the remote node: it work correctly opening the connection and then sending all messages I want; the connection will close only at the end of the communication session.

WHAT HAPPEN ON NJ?

On NJ

  • Open connection whit remote node;
  • Connection is open;
  • Send first message to remote node;
  • Receive correct answer from remote node;
  • Send another ore the same message to remote node;
  • Receive an unknown command answer from remote node. WHY???

To solve previous problem I need to:

  • Close the open connection;
  • Wait the time to reopen it;
  • Reopen connection;
  • send the message;
  • receive the correct answer from the remote node;
  • Close connection
  • Wait the time to reopen it;
  • Reopen connection;
  • send the message;
  • receive the correct answer from the remote node;
  • close connection
  • and so on...

Could someone help me to solve this problem opening the connection only once and then close it at the end of the end of communication session?!

 

THANK YOU

Share this post


Link to post
Share on other sites

No reason I can think of why you cannot send more than one message with port open.  I do 3 commands with one open regularly.

I assume you mean Class 3 communications, with CIPOpen, CIPClose...

Share this post


Link to post
Share on other sites

SORRY but I cannot attach the capture of the program... anyway... I'm using TCP connction with socket

Have you same example to suggest me about CIPOpen usage?

 

Share this post


Link to post
Share on other sites

Which instructions are you using in your program?

Share this post


Link to post
Share on other sites

Unfortunately I cannot able to attach any file to my post... anyway:

SktTCPConnect

SKTTCPsend, SKTTCPRCV and all other SKTTCP___instructions.

The thing that is very strange is that using this connection with other devices like TDKLambda power supplies the connection works without any problem. In this case it seems that sending the second command the buffer is dusty and then the command is different fro the command I send. Maybe closing the cnnection this buffer become clean.

Have you some suggestion?

Share this post


Link to post
Share on other sites

Using Multiway for terminal connection I use TCP mode Client: does it mean that the client is the remote node or the PLC?

Share this post


Link to post
Share on other sites

Not sure, I haven't used the socket commands, only the CIP messaging ones.

Share this post


Link to post
Share on other sites

The intent of TCP is to keep the connection open, so you should not need to close it unless there is an error with the connection.

Quote

In this case it seems that sending the second command the buffer is dusty and then the command is different fro the command I send

What do you mean 'dusty' ? Is that the command you have sent?

Are you sending the correct data, including start/end/byte count?

 

Share this post


Link to post
Share on other sites

I don't see where you are clearing the buffer. Here is an example that I've used to receive bytes on an NX102. I haven't tried the NX102 as a server.

// Start sequence when Trigger changes to TRUE.
IF ((Trigger=TRUE) AND (DoTCP=FALSE) AND (_EIP2_EtnOnlineSta=TRUE)) THEN
 DoTCP :=TRUE;
 Stage :=INT#1;
 SktTCPConnect_instance(Execute:=FALSE);   // Initialize instance.
 SktClearBuf_instance(Execute:=FALSE);   // Initialize instance.
 SktGetTCPStatus_instance(Execute:=FALSE);   // Initialize instance.
 SktTCPSend_instance(   // Initialize instance.
  Execute :=FALSE, 
  SendDat :=SendSocketDat[0]);   // Dummy
 SktTCPRcv_instance(   // Initialize instance.
  Execute :=FALSE,
  RcvDat :=RcvSocketDat[0]);   // Dummy
 SktClose_instance(Execute:=FALSE);   // Initialize instance.
END_IF;
IF (DoTCP=TRUE) THEN
 CASE Stage OF
 1 : // Connection request
  SktTCPConnect_instance(
   Execute :=TRUE,
   SrcTcpPort :=UINT#0,  // Local TCP port number Automatically assigned
   DstAdr :='192.168.251.57',  // Remote IP address
   DstTcpPort :=UINT#6000,   // Destination TCP port number
   Socket =>WkSocket);   // Socket
  IF (SktTCPConnect_instance.Done=TRUE) THEN
   Stage :=INT#2;   // Normal end
  ELSIF (SktTCPConnect_instance.Error=TRUE) THEN
   Stage :=INT#10;   // Error end
END_IF;
 2 :   // Receive buffer clear
  SktClearBuf_instance(
  Execute :=TRUE,
  Socket :=WkSocket);   // Socket
  IF (SktClearBuf_instance.Done=TRUE) THEN
   Stage :=INT#3;   //Normal end
  ELSIF (SktClearBuf_instance.Error=TRUE) THEN
   Stage :=INT#20;   //Error end
  END_IF;
  
 3 :   // Status read request
  SktGetTCPStatus_instance(
  Execute :=TRUE,
  Socket :=WkSocket);   // Socket
  IF (SktGetTCPStatus_instance.Done=TRUE) THEN
   Stage :=INT#4;   // Normal end
  ELSIF (SktGetTCPStatus_instance.Error=TRUE) THEN
   Stage :=INT#30;   // Error end
  END_IF;
  
 4 :   // Send request
  SktTCPSend_instance(
  Execute :=TRUE,
  Socket :=WkSocket,   // Socket
  SendDat :=SendSocketDat[0],   // Send data
  Size :=UINT#2000);   // Send data size
  IF (SktTCPSend_instance.Done=TRUE) THEN
   Stage :=INT#5;   // Normal end
  ELSIF (SktTCPSend_instance.Error=TRUE) THEN
   Stage :=INT#40;   // Error end
  END_IF;
  
 5 :   // Receive request
  SktTCPRcv_instance(
  Execute :=TRUE,
  Socket :=WkSocket,   // Socket
  TimeOut :=UINT#0,   // Timeout value
  Size :=UINT#2000,   // Receive data size
  RcvDat :=RcvSocketDat[0]);   // Receive data
  IF (SktTCPRcv_instance.Done=TRUE) THEN
   Stage :=INT#6;   // Normal end
  ELSIF (SktTCPRcv_instance.Error=TRUE) THEN
   Stage :=INT#50;   // Error end
  END_IF;
  
 6 :   // Request to close the socket
  SktClose_instance(
  Execute :=TRUE,
  Socket :=WkSocket);   // Socket
 IF (SktClose_instance.Done=TRUE) THEN
  Stage :=INT#0;   // Normal end
 ELSIF (SktClose_instance.Error=TRUE) THEN
  Stage :=INT#60;   // Error end
 END_IF;
 
 0 :   // Normal end
  DoTCP :=FALSE;
  Trigger :=FALSE;
 ELSE   // Interrupted by error.
  DoTCP :=FALSE;
  Trigger :=FALSE;
 END_CASE;
END_IF;
Edited by IO_Rack

Share this post


Link to post
Share on other sites
Quote

Here is an example that I've used to receive bytes on an NX102.

Looks identical to what I have done... :-), except I translated it to ladder for readability for me.

 

Quote

I haven't tried the NX102 as a server.

I have done both, simple change on the block type only :idea:

Share this post


Link to post
Share on other sites

Dears,

I have the similar problem. The peers are a PC and an NX1P2.

I have to send and receive 5 commands and answers. I made a function block.This block makes the commands, and tries to send it via tcp socket (within the same block). The fb based on the help, and I/O_rack's solution, the difference is mine tries to send-receive 5 times instead 1.

The first command is sent correctly, the answer is received correctly, but the others are not. Sends nothing, and receive nothing.

What is the correct way to do this?

- using two FB-s, where the first makes the commands,and calls the second one, which makes the send-receive? But how, completely with connect.etc.. instructions?

- or the first FB makes commands, and opens the connection (SktTcpConnect, SktClearBuf, etc) and calls the second one, what sends and receives (SktTcpSend, SktGetTcpStatus, SktTcpRcv)?

Has Somebody made some similar?

Thanks in advance, and Merry Christmas!

Share this post


Link to post
Share on other sites

you will need to post what you have done so far, so that it can be viewed & commented on.

Share this post


Link to post
Share on other sites
Quote

you will need to post what you have done so far, so that it can be viewed & commented on.

OK, I attached a simplified version what I try.The first send-receive pair is OK, but only the first.

What is the correct way to send and receive more packets?

tcp.smc2

Share this post


Link to post
Share on other sites

Have you created that 'DoTCP' function block yourself, or got it from somewhere?

I haven't gone through it completely yet, but why is it wrapped up in a FB? Is there multiple instances, or just done for re-useability?

Share this post


Link to post
Share on other sites
Quote

Have you created that 'DoTCP' function block yourself, or got it from somewhere?

The block generally based on the example provided on the help, and the "NX-series CPU built-in ethernet/IP" manual, i just implement a jump for sending-receiving.

FB is just for re-usability. I tried to put in all things in a periodic task, as the local omron representative suggested, but the result was the same.

Unfortunately i can not test it on the controller at this moment.

Generally, bad idea put this into anFB?

Share this post


Link to post
Share on other sites
9 hours ago, acidum said:

Generally, bad idea put this into anFB?

nope, just was wondering why as the implementation is not directly obvious for re-use (input/output variables etc), Saying that, you can set the 'Comm_FB' instance attributes from outside the FB anyway. (similar to the omron examples)

 

On 12/26/2020 at 10:07 PM, acidum said:

The first send-receive pair is OK, but only the first.

What is the correct way to send and receive more packets?

Is your requirement to keep the connection open & continuously send/receive?

I suspect this code here is your problem.

  42:
  RecArray2 := RcvSocketDat;
  Stage :=INT#43;
  

Stage == 43 is close socket. 

If your intent is to send/receive continuously, then there is no need to close the socket once the data is received.

 

Without doing all the leg work for you, I would consider the following:

1.Moving Stages 40-41-42 to be always running if 'DoTCP' is True & socket.IsConnected

2. Either alternating 500-510 or running them both at the same time, depending on the server requirements. (applications I have done worked this way..)

 

Share this post


Link to post
Share on other sites

Dear lostcontrol,thanks for your answer.

I tried to close the connection first, maybe this is the problem. But from a windows sofware, i can run the commands and receive the answers if the connection is open. This sw calls this "persistent tcp connection".

Quote

If your intent is to send/receive continuously, then there is no need to close the socket once the data is received.

This thing is not clear for me at this moment. As i mentioned, currently i am far from the controller, so i know very less about the cycletime, but it seems, i can not wait for the necessary 1-2 min for the re-opening. Instead i keep the connection open.

I made a dirty routine in LAD (because the local Omron's engineer prefers that) but i make some modification on the FB about your comment too.

If you let me more more question:if (let's say) the communication works perfectly,and i keep the socket open when would be necessary to close it?
In manual mode i have to communicate for the PC (for test and setup reasons) so..

I just simply keep it open until power off? This won't be problem?

Kind regards: Acidum

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now