1

So, I'm having a problem with sending data from a C# client to a Java Server. The connection is going through, however I'm messing something up somewhere I guess.

Here's the ServerSided Code

package com.chris.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;


public class Server implements Runnable
{
    private String serverName;
    private boolean isRunning;

private ServerSocket serverSocket;
private Socket clientSocket;

public Server(String name, int port)
{
    try 
    {
        this.serverName = name;
        this.serverSocket = new ServerSocket(port);
        this.isRunning = true;
        new Thread(this).start();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
}

private BufferedReader recv;

public void run()
{
    while(isRunning)
    {
        try 
        {
            clientSocket = serverSocket.accept();
            System.out.println("Client Connected from " + clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort());

            recv = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            System.out.println("Data Recieved: " + recv.readLine());

            clientSocket.close();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
}
}

Here is the Client Code

lass TCPClient
{
    private TcpClient Client;
    private NetworkStream Stream;

    private Byte[] Data;

    public TCPClient(string address, int port)
    {
        Client = new TcpClient();
        Client.Connect(address, port);

        Stream = Client.GetStream();

        SendData("Test Data");

        while (Client.Connected)
        {

        }
    }

    public void SendData(string message)
    {
        Data = System.Text.Encoding.ASCII.GetBytes(message);
        Stream.Write(Data, 0, Data.Length);

        Console.WriteLine("Sent: {0}", message);
    }
}

The server registers the connection, and the client seems to think that it has sent the data, however I can't tell if it's the Client not sending the Data or if it's the Server not receiving it. Considering the Console.Writeline is just printing out the message that was converted into bytes, I can't tell.

1
  • Hi, do you have the final solution for this problem? I have the same problem, but I couldn't get the right solution :( Commented Dec 29, 2016 at 9:20

4 Answers 4

2

If you want to work with JSON, refer to this excellent article on getting Java to send message serializing your java type to JSON and on receiving C# to Deserealize to a C# type.

Excerpt in Java:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import com.google.gson.Gson;

public class GuyServer {
 public static void main(String[] args)
 throws IOException {
      Gson gson = new Gson();
      ServerSocket serverSocket = new ServerSocket(16001);
      System.out.println("Listening on port 16001. " 
              + "Press enter to quit "
              + "after the next connection.");
      while (System.in.available() == 0) {
           Socket socket = serverSocket.accept();
           System.out.println("A client has connected." 
               + " Sending a new Guy down the pipe.");
           PrintWriter out =
               new PrintWriter(socket.getOutputStream(),
                   true);
           Guy guy = Guy.getRandomGuy();
           String json = gson.toJson(guy);
           out.print(json);
           out.close();
           socket.close();
       }
      System.out.println("Quitting...");
      serverSocket.close();
  }
}

C# End:

using System;
using System.IO;
using System.Net.Sockets;
using System.Web.Script.Serialization;

class GuyClient
{
     static void Main(string[] args)
     {
          String input;

          using (TcpClient tcpClient = 
                  new TcpClient("localhost", 16001))
          using (NetworkStream networkStream = 
                  tcpClient.GetStream())
          using (StreamReader streamReader = 
                  new StreamReader(networkStream))
          {
               input = streamReader.ReadToEnd();
           }

          Console.WriteLine("Received data: " + input + "\n");

          JavaScriptSerializer javaScriptSerializer = 
                  new JavaScriptSerializer();
          Guy bob = javaScriptSerializer
                  .Deserialize<Guy>(input) as Guy;
          Console.WriteLine(bob.ToString());
      }
}

Java Class

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Guy {
     private String name;
     public String getName() {
          return name;
      }     
 }

}

C# Serlizable class

using System;
using System.Collections.Generic;

[Serializable]
class Guy
{
     public string Name { get; set; }    
}

I cleaned this up a bit to make it easier to understand. It won't compile but you get the idea.

Sign up to request clarification or add additional context in comments.

Comments

1

C# TCP Client: (this updates the 1st answer), noted that in C# using BinaryWriter is similar to DataOutputStream in Java:

Define your const of MAX_BUFFER_SIZE=1024 (example) somewhere in your code!

public static void WriteString(BinaryWriter os, string value)  {
            if (value!=null) {
                byte[] array = System.Text.Encoding.Unicode.GetBytes(value);
                WriteBuffer(os,array);
            } else {
                WriteInt(os,0);
            }
        }

public static void WriteBuffer(BinaryWriter os, byte[] array) {
            if ((array!=null) && (array.Length > 0) && (array.Length < MAX_BUFFER_SIZE)) {
                WriteInt(os,array.Length);
                os.Write(array);
            } else {
                WriteInt(os,0);
            }
        }

public static void WriteInt(BinaryWriter outStream, int value)  {
            byte[] buffer = BitConverter.GetBytes(value);
            //  Array.Reverse(buffer);
            outStream.Write(buffer);
        }

1 Comment

After putting this all together, doing the following: WriteString(bw, "hello world"); Results in: h[]e[]l[]l[]o[] []w[]o[]r[]l[]d
0

Java TCP client: you should use DataInputStream and DataOutputStream separately to send and receive data:

try
                    {
                        mOutStream = new DataOutputStream(mClientSocket.getOutputStream());
                        mInStream = new DataInputStream(mClientSocket.getInputStream());
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }

Example of manipulating the output data stream (send out):

public static void WriteString(DataOutputStream os, String value) throws IOException {
        if (value!=null) {
            byte[] array = value.getBytes(CHARSET);
            WriteBuffer(os,array);
        } else {
            WriteInt(os,0);
        }
    }

public static void WriteBuffer(DataOutputStream os, byte[] array) throws IOException {
        if ((array!=null) && (array.length > 0) && (array.length <= MAX_BUFFER_SIZE)) {
            WriteInt(os,array.length);
            os.write(array);
            //os.flush();
        } else {
            WriteInt(os,0);
        }
    }

public static void WriteInt(DataOutputStream os, int value) throws IOException {
        byte[] intAsBytes = ConvertIntToBytes(value);
        os.write(intAsBytes);
        //os.flush();
    }

Example of using Input stream (receive):

public static String ReadString(DataInputStream is) throws IOException {
        String ret=null;
        int len = ReadInt(is);
        if ((len == 0) || (len > MAX_BUFFER_SIZE)) {
            ret = "";
        } else {
            byte[] buffer = new byte[len];
            is.readFully(buffer, 0, len);
            ret = new String(buffer, CHARSET);
        }
        return (ret);
    }

public static int ReadInt(DataInputStream is) throws IOException {
        int ret=0;
        byte[] intAsBytes = new byte[4];
        // this will just block forever...
        is.readFully(intAsBytes);
        ret = ConvertBytesToInt(intAsBytes);
        return (ret);
    }

public static int ConvertBytesToInt( byte[] array) {
        int rv = 0;
        for ( int x = 3; x >= 0; x-- )
        {
            long bv = array[ x ];
            if ( x < 3 & bv < 0 ) // keeping the sign intact???
                bv +=256;
            //rv *= 256;
            rv = rv << 8;
            rv += bv;
        }
        return rv;
    }

2 Comments

This is for sending data from a Java Client, however I'm sending the Data from a C# Client. How would I properly go about handling when data is recieved using a DataInputStream (Currently googling this)
Pls see my next answer (separated for the convenience). C# not so different from Java except for using diff names in IO lib.
0

What worked for me: I had to append a byte equal to 0 to my send buffer.

Excerpt from IBM:

The end-of-message marker technique:

A third technique most often seen in C programs is to send a null-terminated string. A null-terminated string is a string of bytes terminated by a byte of binary 0.

Other excerpt:

How read() handles zero-byte STREAMS messages is determined by the current read mode setting. In byte-stream mode, read() accepts data until it has read N bytes, or until there is no more data to read, or until a zero-byte message block is encountered.

2 Comments

Please consider explaining in detail why that helps.
Seems so, but explanations of solutions should be in the answer post, not in a comment.

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.