How to send a binary stream from Java-client to C#-server via Tcp?

In summary: Main(string[] args){HWServer("tcp://localhost:2000");}}In summary, the client is sending "Hello" to the server, but the server is not receiving it.
  • #1
user366312
Gold Member
89
3
TL;DR Summary
I have a C# server. I need to connect a Java client to it, and make them interact.
The following is a client-side C# code:

C# client:
string Host = "localhost";
int Port = 2000;

TcpClient Tcp = new TcpClient(Host, Port);

NetworkStream stream = Tcp.GetStream();
reader = new BinaryReader(stream);
writer = new BinaryWriter(stream);

writer.Write("Hello");
string str = reader.ReadString();

I have written the following Java code:

Java Client:
InetAddress ip = InetAddress.getByName("localhost");

    int PORT_NO = 2000;
    Socket socket = new Socket(ip, PORT_NO);

    // obtaining input and out streams
    DataInputStream reader = new DataInputStream(socket.getInputStream());
    DataOutputStream writer = new DataOutputStream(socket.getOutputStream());

    writer.writeChars("Hello");
    String str = reader.readUTF();

But, my java code isn't working.

C#-Server and C#-clients are running okay. The C#-server seems to be not receiving the string sent by Java client.

How can I do what I need? What would be the Java equivalent of this code?
 
Technology news on Phys.org
  • #2
Have you looked at zeromq. It would be the best way to do this cross language scheme.

http://zeromq.org/
http://zguide.zeromq.org/page:all
Look for the request-reply pattern and you will see the example is written in C#, Java and many other languages.

c# server code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using ZeroMQ;

namespace Examples
{
    static partial class Program
    {
        public static void HWServer(string[] args)
        {
            //
            // Hello World server
            //
            // Author: metadings
            //

            if (args == null || args.Length < 1)
            {
                Console.WriteLine();
                Console.WriteLine("Usage: ./{0} HWServer [Name]", AppDomain.CurrentDomain.FriendlyName);
                Console.WriteLine();
                Console.WriteLine("    Name   Your name. Default: World");
                Console.WriteLine();
                args = new string[] { "World" };
            }

            string name = args[0];

            // Create
            using (var context = new ZContext())
            using (var responder = new ZSocket(context, ZSocketType.REP))
            {
                // Bind
                responder.Bind("tcp://*:5555");

                while (true)
                {
                    // Receive
                    using (ZFrame request = responder.ReceiveFrame())
                    {
                        Console.WriteLine("Received {0}", request.ReadString());

                        // Do some work
                        Thread.Sleep(1);

                        // Send
                        responder.Send(new ZFrame(name));
                    }
                }
            }
        }
    }
}

and the java client code:

java client:
package guide;

//
//  Hello World client in Java
//  Connects REQ socket to tcp://localhost:5555
//  Sends "Hello" to server, expects "World" back
//

import org.zeromq.SocketType;
import org.zeromq.ZMQ;
import org.zeromq.ZContext;

public class hwclient
{
    public static void main(String[] args)
    {
        try (ZContext context = new ZContext()) {
            //  Socket to talk to server
            System.out.println("Connecting to hello world server");

            ZMQ.Socket socket = context.createSocket(SocketType.REQ);
            socket.connect("tcp://localhost:5555");

            for (int requestNbr = 0; requestNbr != 10; requestNbr++) {
                String request = "Hello";
                System.out.println("Sending Hello " + requestNbr);
                socket.send(request.getBytes(ZMQ.CHARSET), 0);

                byte[] reply = socket.recv(0);
                System.out.println(
                    "Received " + new String(reply, ZMQ.CHARSET) + " " +
                    requestNbr
                );
            }
        }
    }
}
 
  • #3
jedishrfu said:
Have you looked at zeromq.

This might be overkill if the communication needed is very basic. Also, there's something to be said for trying to use the built-in APIs of the language in order to see how they work, before trying to use a third-party package.
 
  • Like
Likes Paul Colby
  • #4
user366312 said:
The C#-server seems to be not receiving the string sent by Java client.

Are you getting any error messages? You should be if the communication is not working.
 
  • Like
Likes jedishrfu
  • #5
PeterDonis said:
Are you getting any error messages? You should be if the communication is not working.

No, I am not getting any error message.
 
  • #6
PeterDonis said:
This might be overkill if the communication needed is very basic. Also, there's something to be said for trying to use the built-in APIs of the language in order to see how they work, before trying to use a third-party package.

That would be true except the OP is working across different languages it seems and zeromq is the best practices solution for microservices implementations.
 
  • #7
jedishrfu said:
the OP is working across different languages

Yes, but he's just trying to send and receive bare strings for simple testing. Any language should be able to do that with its own socket APIs.
 
  • #8
user366312 said:
No, I am not getting any error message.

That doesn't seem possible; if the Java client isn't able to connect to what you're telling it to connect to, or to send the data where you're telling it to send it, it should give an error message back. Unless your Java client is actually connecting to something else besides your C# server. (I'm focusing on the client because if the C# server works with a C# client, that indicates to me that the C# code is not what's causing the problem.) Could anything else be listening on port 2000?
 
  • Like
Likes jedishrfu
  • #10
PeterDonis said:
That doesn't seem possible;

This is what happening right now.
 
  • #11
jedishrfu said:
You should check if the port is in use and who is connected to it.

Here's some info on some apps that might be connected:

https://www.speedguide.net/port.php?port=2000

I changed the port to 4321. Problem persists.
 
  • #13
user366312 said:
This is what happening right now.

Are you getting any output at all from the Java client? Note that as you've written the code here, for both the C# and the Java clients, there is no output to the console or anywhere else; the data read from the socket just gets stored in a variable. Is there more code you're not showing us?
 
  • #14
PeterDonis said:
Are you getting any output at all from the Java client Note that as you've written the code here, for both the C# and the Java clients, there is no output to the console or anywhere else; the data read from the socket just gets stored in a variable. Is there more code you're not showing us?

It seems that the java client gives some error message when the server is closed. I.e. it recognizes that the server port is closed.

But, other than that, no other response. Only local I/O are visible on the console..

https://stackoverflow.com/questions...-a-binary-stream-from-java-to-c-sharp-via-tcp
This is my post to SO. Check it.
 
  • #15
@user366312 you linked to a StackExchange thread, but that just has the same code you showed us here. Is that all the code there is? If so, your C# client would not output the string it receives from the server, so how do you know the C# client is working?

Also, we haven't seen the C# server code. What is the server supposed to do? Just echo back whatever it receives from the client? How does it do that?
 
  • #16
PeterDonis said:
@user366312 you linked to a StackExchange thread, but that just has the same code you showed us here. Is that all the code there is? If so, your C# client would not output the string it receives from the server, so how do you know the C# client is working?

Also, we haven't seen the C# server code. What is the server supposed to do? Just echo back whatever it receives from the client? How does it do that?

I have to implement simple key-value system. Each user can add to the system a new key-value pair. If the key has already existed, then the user who added this key should decide if the value should be updated.

Here is server code:

https://stackoverflow.com/questions...server-application-to-manipulate-a-dictionary
 
  • #17
user366312 said:
Here is server code

Ok, so it looks like you are using ReadString and Write in the server code as well as the C# client code. So the responses in the StackExchange thread talking about how those functions use a format that is specific to C#, which Java does not know how to parse, might be relevant. For a multi-language implementation, it's best to use functions that read and write raw bytes, and have your code explicitly encode and decode them to whatever data types you want to use.

I'm also still confused about how you know the C# client is working with no console output.
 
  • #18
PeterDonis said:
For a multi-language implementation, it's best to use functions that read and write raw bytes, and have your code explicitly encode and decode them to whatever data types you want to use.

I have modified my program to do that. But, something is still wrong. see the code below.

PeterDonis said:
I'm also still confused about how you know the C# client is working with no console output.

C# client is working fine and they are coded to show messages whenever they connect.

Java client is not working.

Java Client:
// Java implementation for multithreaded chat client
// Save file as Client.java
package firstjavaclientprogramtest; 

import java.io.*;
import java.net.*;
import java.util.Scanner;
 
public class FirstJavaClientProgramTest 
{
    final static int PORT_NO = 4321;
 
    public static void main(String args[]) throws UnknownHostException, IOException 
    {
        Scanner console = new Scanner(System.in);// user input scanner
          
        // getting localhost ip
        InetAddress ip = InetAddress.getByName("localhost");
          
        // establish the connection
        Socket socket = new Socket(ip, PORT_NO);
          
        // obtaining input and out streams
        BinaryReader reader = new BinaryReader(socket);
        BinaryWriter writer = new BinaryWriter(socket);
 
        //send the client ID
        String ID = AlphaNumRandom.randomString(5);
        System.out.println(ID);
        writer.Write(ID);
        
        // Writing to the server
        Thread sendMessage;
        sendMessage = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    while (true)
                    {   
                        System.out.println("Client prompt (\"?\" for help) # ");
                        String str = console.nextLine(); // read the message to deliver.
                      
                        switch (str)
                        {
                            case "?":
                                System.out.println("add = add key value\n ls = list keys\n upd = update key value\n exit=terminate program");
                                break;
                                
                            case "add":
                                System.out.println("Enter key : ");
                                String key = console.nextLine();
                                System.out.println("Enter value : ");
                                String value = console.nextLine();
                                writer.Write(key);
                                writer.Write(value);
                                break;
                                
                            case "upd":
                                System.out.println("Enter key : ");
                                String keyToUpd = console.nextLine();
                                System.out.println("Enter val : ");
                                String valToUpd = console.nextLine();
                                writer.Write(keyToUpd);
                                writer.Write(valToUpd);
                                break;
                                
                            case "clear":
                                Consoles.Clear();
                                break;
                        }
                        
                        ///////////writer.write(str); // write on the output stream
                    }
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        });
          
        // Reading from Server
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run()
            {
                while (true)
                {
                    try
                    {
                        // read the message sent to this client
                        String msg = reader.Read();
                        
                        System.out.println(msg);
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        });
        sendMessage.start();
        readMessage.start(); 
    }//:~ main
}//:~ class
BinaryReader:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package firstjavaclientprogramtest;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 *
 * @author Lenovo
 */
public class BinaryReader
{
    private DataInputStream reader;
    
    public BinaryReader(Socket socket) throws IOException
    {
        reader = new DataInputStream(socket.getInputStream());
    }
    
    public String Read() throws IOException
    {
        int len = reader.readInt();
        byte[] bytes = new byte[len];
        reader.read(bytes, 0, len);
        String str = new String(bytes, StandardCharsets.UTF_8);
        
        return str;
    }
}

BinaryWriter:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package firstjavaclientprogramtest;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 *
 * @author Lenovo
 */
public class BinaryWriter
{
    DataOutputStream writer;
    
    public BinaryWriter(Socket socket) throws IOException
    {
        writer = new DataOutputStream(socket.getOutputStream());
    }
    
    public void Write(String str) throws IOException
    {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        writer.writeInt(bytes.length);
        writer.write(bytes, 0, bytes.length);
    }
}
 
  • #19
user366312 said:
Java client is not working.

What does "not working" mean? Can you post an actual console session showing what happens when the program is run?
 
  • #20
user366312 said:
I changed the port to 4321. Problem persists.

Did you check if it’s in use? Just changing the port does little to solve the problem unless by luck it works.
 
  • #21
As @PeterDonis has said we can’t help if we don’t what exact error you are receiving if any.

If the c# client works how do you know?
 
  • #22
user366312 said:
No, I am not getting any error message.

It appears you are not checking for an error status, though. Are you?
 
  • #23
I haven't read all details in this thread and may have missed if this has already been mentioned, but a common issue in general when writing and then reading on same socket (or blocking in other ways after writing) is to forget to flush the writer when you want the data to be sent. If the BinaryWriter supports buffered output it should also have a flush method you can call after writing your data to ensure it is pushed to the socket and sent.
 
  • Like
Likes jedishrfu
  • #25
jedishrfu said:
As @PeterDonis has said we can’t help if we don’t what exact error you are receiving if any.

If the c# client works how do you know?

Check the source code.

 
  • #26
user366312 said:
Check the source code.

Checking the source code doesn't tell you that the client works in the real world. You have to run it, and you have to have some way of telling that it does the right thing when you run it. That's why we keep asking for something like a transcript of the console session when you actually run it.

Donald Knuth has a saying that is relevant here: "Beware of bugs in the above code; I have only proved it correct, not tried it."

https://en.wikiquote.org/wiki/Donald_Knuth
 
  • #27
PeterDonis said:
That's why we keep asking for something like a transcript of the console session when you actually run it.

Which console? C# or Java?
 
  • #30
Svein said:
The protocol you need to implement is FTP

Why would he want to do that? He's not trying to transfer files.
 
  • #31
PeterDonis said:
Why would he want to do that? He's not trying to transfer files.
Transferring a bit stream has the same inherent problems as transferring binary files. It is not dead easy - FTP has gone through several revisions.
 
  • Like
Likes jedishrfu
  • #32
user366312 said:
Which console? C# or Java?

Both the C# will show that it works and the Java one will show something else that may be key to your problem.
 
  • #33
jedishrfu said:
Both the C# will show that it works and the Java one will show something else that may be key to your problem.

I have solved the problem. Never mind.

I thank all of you for your time and effort.
 
  • #35
jedishrfu said:
That's great!

So what was the problem?

There was difference in r/w data format.

I am now using raw data format on both ends. I am using byte arrays.
 
<h2>1. How do I establish a TCP connection between a Java client and a C# server?</h2><p>To establish a TCP connection between a Java client and a C# server, you can use the Socket class in Java and the TcpListener class in C#. The client will use the Socket class to connect to the server's IP address and port number, while the server will use the TcpListener class to listen for incoming connections on a specific port.</p><h2>2. How do I send a binary stream from Java to C# over TCP?</h2><p>To send a binary stream from Java to C# over TCP, you can use the InputStream and OutputStream classes in Java to read and write the binary data, and the NetworkStream class in C# to receive and send the binary data. It is important to ensure that both the client and server are using the same encoding and decoding methods for the binary data.</p><h2>3. What is the best way to handle errors and exceptions when sending a binary stream between Java and C#?</h2><p>The best way to handle errors and exceptions when sending a binary stream between Java and C# is to use try-catch blocks in both the client and server code. This will allow you to handle any errors that may occur during the connection, transmission, or decoding of the binary data. It is also recommended to use a protocol or format for the binary data that includes error checking and handling mechanisms.</p><h2>4. Can I send multiple binary streams over the same TCP connection?</h2><p>Yes, you can send multiple binary streams over the same TCP connection. This can be achieved by using a protocol or format for the binary data that includes a way to identify and separate different streams of data. For example, you can use a header or delimiter to indicate the start and end of each binary stream.</p><h2>5. Is it possible to send a binary stream from a C# server to a Java client?</h2><p>Yes, it is possible to send a binary stream from a C# server to a Java client over TCP. The process is similar to sending a binary stream from Java to C#, but the roles of the client and server will be reversed. The C# server will use the Socket class to connect to the Java client's IP address and port number, while the Java client will use the InputStream and OutputStream classes to receive and send the binary data.</p>

1. How do I establish a TCP connection between a Java client and a C# server?

To establish a TCP connection between a Java client and a C# server, you can use the Socket class in Java and the TcpListener class in C#. The client will use the Socket class to connect to the server's IP address and port number, while the server will use the TcpListener class to listen for incoming connections on a specific port.

2. How do I send a binary stream from Java to C# over TCP?

To send a binary stream from Java to C# over TCP, you can use the InputStream and OutputStream classes in Java to read and write the binary data, and the NetworkStream class in C# to receive and send the binary data. It is important to ensure that both the client and server are using the same encoding and decoding methods for the binary data.

3. What is the best way to handle errors and exceptions when sending a binary stream between Java and C#?

The best way to handle errors and exceptions when sending a binary stream between Java and C# is to use try-catch blocks in both the client and server code. This will allow you to handle any errors that may occur during the connection, transmission, or decoding of the binary data. It is also recommended to use a protocol or format for the binary data that includes error checking and handling mechanisms.

4. Can I send multiple binary streams over the same TCP connection?

Yes, you can send multiple binary streams over the same TCP connection. This can be achieved by using a protocol or format for the binary data that includes a way to identify and separate different streams of data. For example, you can use a header or delimiter to indicate the start and end of each binary stream.

5. Is it possible to send a binary stream from a C# server to a Java client?

Yes, it is possible to send a binary stream from a C# server to a Java client over TCP. The process is similar to sending a binary stream from Java to C#, but the roles of the client and server will be reversed. The C# server will use the Socket class to connect to the Java client's IP address and port number, while the Java client will use the InputStream and OutputStream classes to receive and send the binary data.

Similar threads

  • Programming and Computer Science
Replies
7
Views
332
  • Engineering and Comp Sci Homework Help
Replies
10
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
12K
Back
Top