I have written up a TCP/IP Background Task. The robot is acting as the server and I am trying to constantly listen to incoming clients. I am currently getting an error every time I synchronise the robot with the Kuka Sunrise Workbench. The error seems to be that when I reconnect I am unable to as the Socket is already Bound. This obviously means I am not closing the socket. But I am not too sure how to close the socket on an abrupt termination of the TCP/IP background task, especially when I hit the task to stop or when I go to synchronise.
Is there a way that I could attempt to close the socket before the background task is shutoff? OTherwise I have to power cycle after everytime I synchronise.
package application;
import javax.inject.Inject;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
import com.kuka.roboticsAPI.applicationModel.tasks.CycleBehavior;
import com.kuka.roboticsAPI.applicationModel.tasks.RoboticsAPICyclicBackgroundTask;
/**
* Implementation of a cyclic background task.
* <p>
* It provides the {@link RoboticsAPICyclicBackgroundTask#runCyclic} method
* which will be called cyclically with the specified period.<br>
* Cycle period and initial delay can be set by calling
* {@link RoboticsAPICyclicBackgroundTask#initializeCyclic} method in the
* {@link RoboticsAPIBackgroundTask#initialize()} method of the inheriting
* class.<br>
* The cyclic background task can be terminated via
* {@link RoboticsAPICyclicBackgroundTask#getCyclicFuture()#cancel()} method or
* stopping of the task.
* @see UseRoboticsAPIContext
*
*/
public class TCPServer extends RoboticsAPICyclicBackgroundTask {
@Inject
Socket Server;
byte[] RXRawData = new byte[1024];
private static String RXString = new String();
ServerSocket serversocket;
String delims = "[<>]+";
String tcpconnection = "CLOSED";
private static boolean ServerConnected = false;
private static boolean MessageReceived = false;
private static boolean ApplicationClosed = false;
private static String Test;
@Inject
@Override
public void initialize() {
try {
serversocket = new ServerSocket(30001);
Server = serversocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
initializeCyclic(0, 500, TimeUnit.MILLISECONDS,
CycleBehavior.BestEffort);
}
@Override
public void runCyclic() {
// your task execution starts here
try
{
if(ApplicationClosed == true)
{
ApplicationClosed = false;
}
if(Server.isClosed())
{
serversocket.close();
serversocket = new ServerSocket(30001);
Server = serversocket.accept(); //Block Function, waits till it finds a client\
ServerConnected = true;
}
else
ServerConnected = false;
InputStream input = Server.getInputStream();
DataInputStream in = new DataInputStream(input);
MessageReceived = false;
in.read(RXRawData);
MessageReceived = true;
String RXRawString = new String(RXRawData);
RXString = RXRawString.trim();
//ServerTransfer_("What happend??");
ServerTransfer_("/<MSGRCD><Test1><Test2><Test3><Test4><Test5><Test6>");
String[] tokens = RXString.split(delims,0);
if(tcpconnection.matches(tokens[1]) /*|| SignalTower.getApplicationState()*/)
{
ServerSocketClose_();
ServerConnected = false;
ApplicationClosed = true;
}
try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}
} catch(IOException e) {
try
{
serversocket.close();
serversocket = new ServerSocket(30001);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
//Will call this function in Robot Code when we want to send a message to the PC
public boolean ServerTransfer_(String message)
{
OutputStream output;
try {
output = Server.getOutputStream();
DataOutputStream out = new DataOutputStream(output);
out.writeBytes(message);
message = null;
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
//Test = e.getMessage();
}
return true;
}
public static String getRXString()
{
return RXString;
}
public static boolean getRobotConnected()
{
return ServerConnected;
}
public static boolean getMessageReceived()
{
return MessageReceived;
}
public static boolean getApplicationClosed()
{
return ApplicationClosed;
}
//Will call this function when PC sends message wanting to close connection
public void ServerSocketClose_()
{
try {
Server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Display More
This is my first time writing TCPIP. So I probably havent written it in the most ideal way either. But like I said Im trying to close the serverSocket before it is synchronised. I am not too familar with how a cyclic background task comes to an end or if there is a procedure/function I need to write that is called before it is abruptly closed.