Communication from Java to C++ using ProtoBuf over socket - java

I'm trying to send an message from Java client to C++ server using ProtoBuf over socket. My program hangs while i am trying to create InputStream. Thanks in advance if some one could help me on this and here is my part of client code in java:
String host = "xxxxxxxxx";
int port = xxxx;
Builder builder = CarSelection.Car.newBuilder();
builder.setLabel("Audi");
builder.setValue("A6");
Car car = builder.build();
Socket client = new Socket(host, port);
byte[] result = car.toByteArray() ;
car.writeDelimitedTo(client.getOutputStream());
Car recieveData= car.parseDelimitedFrom(client.getInputStream());
It is able to write to output stream but my program hangs when trying to read from input stream.

Related

Storing and retrieving data from server host using Java

I have an assignment where I have to build a Client-Server communication using Java. So what I did was building a Client-Server connect using Sockets, the following way:
//Client code
Socket socket = new Socket("127.0.0.1", 4999);
//Server code
ServerSocket ss = new ServerSocket(4999);
Socket socket = ss.accept();
System.out.println("Client is connected");
For now, the communication between the client and the server is successful, I am able to send messages from client to server and vice versa. but the main problem is storing data on the server host, we were asked to store relevant data on the server host so the server could send it to the client.
Can someone please explain to me how to store data on the server and how to retrieve it ??
Thanks
To read from the server socket:
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//Do whatever you want with the DataInputStream
Source: https://www.baeldung.com/java-inputstream-server-socket
Then we can move to the input stream processing, here is a sample:
...
int i;
char c;
...
try{
// reads till the end of the stream
while((i = in .read())!=-1) {
// converts integer to character
c = (char)i;
// prints character
System.out.print(c);
}
} catch(Exception e){
//Handle....
} finally {
// Close stream...
}
Source: https://www.tutorialspoint.com/java/io/inputstream_read.htm#:~:text=io.-,InputStream.,the%20returned%20value%20is%20%2D1.
For writing to the socket (the response to the client), just follow the following tutorial, no need to repeat it here:
http://www.avajava.com/tutorials/lessons/how-do-i-write-a-server-socket-that-can-handle-input-and-output.html
I hope it helps

Send Google Protocol buffer messages between C# and Java

I am trying to get a good sample program to send Google protocol buffer messages to and from Java server to c# client. I an using RabbitMQ for this purpose, but I found that RabbitMq service is not that reliable, and crashes some time. As a backup I want to use socket option in case RabbitMq is down.
I have code like this in java
ProtoBuffMessage.MessageProtBuff msgItem = clsBuilder.build();
ByteArrayOutputStream oStream = new ByteArrayOutputStream();
msgItem.writeTo(oStream);
...
...
//Send it to RabbitMQ
m_clsChannel.basicPublish(m_clsAppSettings.getRabbitMqExchangeName(), m_clsAppSettings.getRabbitMqExchangeQueue(), null, oStream.toByteArray());
on C# side I have code like this to receive and parse the data
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: "direct_logs",
type: "direct");
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
exchange: "direct_logs",
routingKey: "amr");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
var routingKey = ea.RoutingKey;
Console.WriteLine(" [x] Received {0}':'{1}'",
routingKey, message);
Messaging.MessageProtBuff.Builder builder = new Messaging.MessageProtBuff.Builder();
builder.MergeFrom(body);
Messaging.MessageProtBuff data = builder.Build();
Console.WriteLine(data.Comment);
}
}
This works with RabbitMq if it is working properly. Now I want to know How do I use sockets to send the same, and receive it at C# client and reconstruct the Object. Preferably I would like to use the same ByteArrayOutputStream oStream object in java code. By converting it to byte array I can send it over the scocket and reconstruct the object at other end.
I have adapted this sample in my code:
http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
but in this tutorial they are sending strings. I want to send the byte array. How to do this at java end and how to parse the same at C# end?

Request File from server using sockets

I am creating a program where an android device requests a file from a Web Server(running python).The server can receive over sockets with no problem the path of the requested file but i dont know how i can make my android device to wait for a responce.
Here is the android code(as a client requesting a file from web server):
try {
Socket socket = null;
socket = new Socket("192.168.1.9", 4000);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
String str = getURL();
output.writeBytes(str);
output.close();
input.close();
socket.close();
{
}
} catch (IOException e) {
}
Log.d("communicationService", "URL transferred with success");
And the python script running on Web Server(It can receive thefile path but i have problem sending the file)
import socket
import sys
HOST, PORT = '192.168.1.9', 4000
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.bind((HOST,PORT))
serverSocket.listen(10)
print 'Server is on and listening to %s ... ' % PORT
while True:
clientSocket, clientAddress = serverSocket.accept()
print 'A client was connected.....'
incomingURL = clientSocket.recv(1024)
print incomingURL
clientSocket.close()
Any advice and tip would be really helpful...
I imagine you should be able to get away with SimpleHTTPServer
If you need to get fancier with a full blown webservice, WSGI is very popular.
On the client side Requests library is by far the easiest way that I've found to make http requests in python. (just had to plug that one because it's that good)
Well i managed to transfer the files in the end(For those that are interested in apps of this kind).What i did was to create another socket and sent a stream back to client.
file = open("path_of_file", "rb")
s = socket.socket()
s = connect((addr,port))
l = file.read(1024)
while (l):
s.send(l)
l.f.read(1024)
file.close()
s.close()

Java Sockets - Sending data from client to server

My objective: send a local variable from the client program to the server program.
I have the client and server connected, and I know how to send string messages from the client to the server.
Example:
private void sendToServer(Socket clientSocket) throws IOException{
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
writer.write("You have connected to the server.");
writer.flush();
writer.close();
}
The above code works perfectly and sends a message.
But what do I do if I want to send data/variables between a client and a server?
For example what if I had a variable float a = 0.5, or a 2d integer array, etc. how would I send that from client to server or vice-versa?
I tried doing the same thing just using writer.write(a) instead, for example, but the inputs for writer.write() are limited, so I feel like I'm approaching it incorrectly.
If there is a better way for me to try to be sending variables aside from using BufferedReaders&BufferedWriters, could you let me know?
Thanks!
When dealing with java client/server communications, if you have full control over both ends and don't anticipate designs changing, you can directly perform encoding directly using Java serialization through the Object*Stream classes.
Example:
ObjectOutputStream output = new ObjectOutputStream(bufferedSocketStream);
output.writeInt(42); // Write a primitive integer
output.writeObject("Hello World"); // Write a string as an object
output.writeObject(myClass); // Write a class instance that you've implemented the "Serialize" interface
output.flush();
/* INPUT */
ObjectInputStream inputStream = new ObjectInputStream(bis);
int value = inputStream.readInt(); // Will receive 42
Object value2 = inputStream.readObject(); // Will receive "Hello World"
Object value3 = inputStream.readObject(); // Will receive your serialized class instance
(see https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html and https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html)

C++ Client and Java Server

I did a Java Socket server, and a C++ Client.
However, the client connects to the server, without problems.
But when I write something client-server, the server doesn't catch the message.
What I'm doing wrong?
A little bit of the code of the Java Server:
DataInputStream dis=new DataInputStream(usrSocket.getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
int data;
while((data = dis.read())>=0) {
out.write(data);
}
byte[] bytes = out.toByteArray();
String decrypt = new String(bytes);
if(decrypt.equals("status")){
System.out.println("Status emitted.");
}
System.out.println("Received a message.");
C++ Client writing:
QByteArray qba;
qba.append(text);
sock->write(qba.data());
qDebug() << "Send status";
I need help with that, thank you very much.
(that variable "text" it's a QString)
EDIT
Java server: That's only one part of all the code, the main thread waits for connections (Socket sock = server.accept()) and create a new thread for each user.
The code that I published of the java server, its one part of that threads for the users.
If you need ALL the code, plese tell me.
I will be waiting the answers!
Thank u very much!
Sorry if I answer ya late.
Try this code for Java Server.
ServerSocket ss = new ServerSocket(Port_No);
Socket incomingClient = ss.accept();
InputStream i = incomingClient.getInputStream();
OutputStream o = incomingClient.getOutputStream(); // Use it write to the Client Socket
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String str = new String();
while ((str = br.readLine())!=null){
// do what you want with the data received in str.
}
As youre using QTcpSocket, it highly likely that you are running the client in the default asynchronous mode. This means after when you write after calling connectToHost, nothing will be sent as the socket is not connected.
Try using:
socket->connectToHost(hostAddress, hostPort, QIODevice::ReadWrite);
if (socket->waitForConnected()) {
QString text = "test string";
QByteArray array;
array.append(string);
qDebug() << socket->write(array);
} else {
// connect error!
}
Your Java code reads the socket until EOS and then prints something, which by the way is not a decryption operation. Your C++ client writes something and never closes the socket. So the server can never get out of the read loop.
If I read it correctly it is caused by the fact that your client is still running. Read() returns number >= 0 until the client socket is closed.

Categories