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

  • Thread starter user366312
  • Start date

user366312

Gold Member
63
2
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?
 
10,361
3,885
Have you looked at zeromq. It would be the best way to do this cross language scheme.



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
                );
            }
        }
    }
}
 
24,390
6,026
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.
 

user366312

Gold Member
63
2
Are you getting any error messages? You should be if the communication is not working.
No, I am not getting any error message.
 
10,361
3,885
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.
 
24,390
6,026
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.
 
24,390
6,026
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?
 
10,361
3,885
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:

 

user366312

Gold Member
63
2
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:

I changed the port to 4321. Problem persists.
 

user366312

Gold Member
63
2

even this solution isn't working.
 
24,390
6,026
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?
 

user366312

Gold Member
63
2
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..


This is my post to SO. Check it.
 
24,390
6,026
@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?
 

user366312

Gold Member
63
2
@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:

 
24,390
6,026
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.
 

user366312

Gold Member
63
2
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.

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);
    }
}
 
10,361
3,885
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?
 

Vanadium 50

Staff Emeritus
Science Advisor
Education Advisor
22,601
4,880

Filip Larsen

Gold Member
1,188
120
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.
 

Want to reply to this thread?

"How to send a binary stream from Java-client to C#-server via Tcp?" You must log in or register to reply here.

Physics Forums Values

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving
Top