0

I am trying to send json messages to a specific ip and port using tcp socket connections. The code seems to work with the initial connection and message submission but when checking the destination server, I do not find the messages. I have a .NET version that runs as well and for some reason trying to send the exact same message works fine. I tried to use wireshark to capture the packet and connection but it seems there is no packets being set at all.

wireshark capture:

wireshark

The code in java :

  try

    {



        clientSocket = new Socket(ipaddress, portnumber);
        outStreamSplunk = new PrintWriter(clientSocket.getOutputStream(), true);
        outStreamSplunk.flush();
        clientSocket.setKeepAlive(true);
        clientSocket.setSoTimeout(1000);


        outStreamSplunk.println(post + "\n");
        System.out.println("SENT MESSAGE: " + post);
        clientSocket.close();

    }
    catch (Exception exc)
    {
         modifiedSentence = "";
    }

and the code in .NET that works:

    ip = "xxx.xxx.x.xxx"
    port = xxxx


    Dim ips As String = Dns.GetHostEntry(ip).AddressList(0).ToString()
    _GLOIP = IPAddress.Parse(ips)
    _port = port

    'initiate the client and get the stream to use
    myTcp = initiate()
    netStream = myTcp.GetStream() 

Try

        If netStream.CanWrite Then
            If Not text.EndsWith(vbCr & vbLf) Then
                text += Environment.NewLine
            End If

            Dim sendBytes As Byte() = Encoding.UTF8.GetBytes(text)
            netStream.Write(sendBytes, 0, sendBytes.Length)

        Else
            err = "cannot write to the stream"
        End If

    Catch ex As Exception
        appLogs.constructLog(err & vbNewLine & ex.Message.ToString, True, True)
        Exit Sub
    End Try

EDIT:

I tried another server as I thought it may be my machine and since the .NET script runs on another machine. Turns out the TCP connection works fine but not sure how to interpret the response:

tcp response

I dont see any errors so perhaps its a problem with the destination server. The only other difference between the .NET version and java version is that the.NET version is writing into byte array. This has me stumped. But if I don't find resolution I will need to do it the hard way and use the .NET version and transfer message somehow from main java code to the .NEt version.

8
  • 3
    That is not a good exception handler... Commented Aug 11, 2016 at 14:54
  • The difference is in the exception handlers... In the .Net version, you are logging the error. In the Java version, you are ignoring it. Add at least a exc.printStackTrace(). Commented Aug 11, 2016 at 14:56
  • Also, the .Net code does not cover establishing a connection in the first place. Since you see no packets going out over the wire in the Java version, it seems likely that that's where your problem lies. At a guess, ipaddress or portnumber is invalid, so that no connection is even attempted (since Wireshark would see the connection attempt). Commented Aug 11, 2016 at 15:02
  • thanks all. Will change exception handler first and try that. Commented Aug 11, 2016 at 15:04
  • no exception is being caught. Does not seem to be any error within the code. I can ping the ip from command prompt and then tried to do a telnet connection and that failed : could not open connection to the host on port, connect failed. Forgive me if I am confusing networking protocols here but just wanted to try everything Commented Aug 11, 2016 at 15:10

2 Answers 2

2

Your Java code is not equivalent to your VB.NET code.


Java

Your use of PrintWriter does not guarantee UTF-8 encoding:

public void println(String x)

Prints a String and then terminates the line. This method behaves as though it invokes print(String) and then println().

public void print(String s)

Prints a string. If the argument is null then the string "null" is printed. Otherwise, the string's characters are converted into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.

So, you are not guaranteed to be sending UTF-8. Instead, use OutputStreamWriter with a UTF-8 Charset assigned to it.

Also, you are sending 2 line terminators, one explicit in the string data and one implicit by println().

Try this:

try
{
    clientSocket = new Socket(ipaddress, portnumber);
    clientSocket.setKeepAlive(true);
    clientSocket.setSoTimeout(1000);

    outStreamSplunk = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8));
    outStreamSplunk.write(post);
    if (!post.endsWith("\r\n"))
        outStreamSplunk.write("\r\n");
    outStreamSplunk.flush();

    System.out.println("SENT MESSAGE: " + post);

    clientSocket.close();
}
catch (Exception exc)
{
    // log exc.toString() as needed....
    return;
}

VB.NET

The code is forcing UTF-8, and only sends one line terminator. However, Environment.NewLine is platform-specific and not guaranteed to be a CRLF, so use vbCrLf instead.

Also, using IPAddress.Parse() to parse the result of AddressList(0).ToString() is redundant overhead since AddressList(0) returns an IPAddress to begin with, so just use it as-is.

Also, if Dns.GetHostEntry() or initialize() fails, you are not catching the exception to log it.

Try this:

'ip = "xxx.xxx.x.xxx"
'port = xxxx

Try
    _GLOIP = Dns.GetHostEntry(ip).AddressList(0)
    _port = port

    'initiate the client and get the stream to use
    myTcp = New TcpClient(New IPEndPoint(_GLOIP, _port))
    netStream = myTcp.GetStream() 

    Dim bufStream As BufferedStream = New BufferedStream(netStream)

    Dim sendBytes As Byte() = Encoding.UTF8.GetBytes(text)
    bufStream.Write(sendBytes, 0, sendBytes.Length)

    If Not text.EndsWith(vbCrLf) Then
        sendBytes = Encoding.UTF8.GetBytes(vbCrLf)
        bufStream.Write(sendBytes, 0, sendBytes.Length)
    End If

    bufStream.Flush()

Catch ex As Exception
    appLogs.constructLog(err & vbNewLine & ex.Message.ToString, True, True)
    Exit Sub
End Try

Alternatively, you could use the TcpClient constructor that accepts a string as input and not call Dns.GetHostEntry() at all:

'ip = "xxx.xxx.x.xxx"
'port = xxxx

_GLOIP = ip
_port = port

...

'initiate the client and get the stream to use
myTcp = New TcpClient(_GLOIP, _port)
Sign up to request clarification or add additional context in comments.

Comments

0

Your flush is in the wrong place. It should be after the write, not before it, where it is completely pointless. Actually you should just close the writer instead of the socket: that wil flush the writer and close the socket. At present the data is never getting out of the writer into the socket.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.