class EchoProtocolTcpTask extends AbstractEchoProtocolTask {

	public QoSTestResult call() throws Exception {
		final QoSTestResult result = initQoSTestResult(QosMeasurementType.ECHO_PROTOCOL);
		try {
			onStart(result);

			try {
				System.out.println("ECHO_PROTOCOL_TCP_TASK: " + getTestServerAddr() + ":" + getTestServerPort());
		    	

		    	if (this.testPort != null && this.testHost != null) {
					try (Socket socket = getSocket(testHost, testPort, false, (int)(timeout/1000000))){
						socket.setSoTimeout((int)(timeout/1000000));
						
						final long startTime = System.nanoTime();
						sendMessage(socket, this.payload + "\n");
						final String testResponse = readLine(socket);
						final long duration = System.nanoTime() - startTime;

						result.getResultMap().put(RESULT, testResponse);
						socket.close();
						if (this.payload.equals(testResponse)) {
							result.getResultMap().put(RESULT_STATUS, "OK");
						} else {
							result.getResultMap().put(RESULT_STATUS, "ERROR");
						}
						result.getResultMap().put(RESULT_RTT_NS, Long.toString(duration));
					}
					catch (SocketTimeoutException e) {
						result.getResultMap().put(RESULT_STATUS, "TIMEOUT");
					}
					catch (Exception e) {
						result.getResultMap().put(RESULT_STATUS, "ERROR");
					}
		    	} else {
		    		result.getResultMap().put(RESULT_STATUS, "ERROR");
				}
				
			}
			catch (Exception e) {
				e.printStackTrace();
				result.getResultMap().put(RESULT_STATUS, "ERROR");
			}
			
			return result;
		}
		catch (Exception e)  {
			throw e;
		}
		finally {

			if (this.testPort != null) {
				result.getResultMap().put(RESULT_PORT, testPort);
			}

			if (this.testHost != null) {
				result.getResultMap().put("echo_protocol_objective_host", this.testHost);
			}

			result.getResultMap().put(RESULT_TIMEOUT, timeout);

			if (this.payload != null) {
				result.getResultMap().put(AbstractEchoProtocolTask.PARAM_PAYLOAD, this.payload);
			}

			result.getResultMap().put(AbstractEchoProtocolTask.RESULT_PROTOCOL, AbstractEchoProtocolTask.PROTOCOL_TCP);

			onEnd(result);
		}
	}

	public  EchoProtocolTcpTask(QualityOfServiceTest nnTest, TaskDesc taskDesc, int threadId);

}