Sending a string from a Java client to a Python server - java

I'm trying to send a simple string from a Java client to a Python server.
Here's the Java client implementation:
Socket socket = new Socket(addr, PORT_NUMBER);
String message = "Hello##2##you\n"
PrintWriter outPrintWriter = new PrintWriter(socket.getOutputStream(),true);
outPrintWriter.println(answerToString);
Here's the Python server implementation:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.settimeout(TIMEOUT)
s.bind(('', PORT_NUMBER))
s.listen(5)
conn, addr = s.accept()
data = conn.recv(4096)
print(data.decode())
strings_received = data.split("##")
But I get the following error while decoding:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xac in position 0: invalid start byte
I read that Java is by default encoding messages to utf-16, so I tried with:
print(data.decode('utf-16'))
But this did not solve the issue as I obtain in output this: "Ԁ" .
Moreover when I get to the next line I get the following error:
TypeError: a bytes-like object is required, not 'str'
How to correctly send the string from Java to Python?

Related

Read from InputStream in Swift from Java Server

as the title says, I'm trying to read from an InputStream in Swift. I'm new to Swift so I'm having some troubles regarding how to read from the InputStream a message sent from the Java Server.
Java Server Code:
byte[] toSend = sec.initiateDH;
out.writeInt(toSend.length);
out.write(toSend);
Swift Client Code
init(_ ipAddress: String, _ port: Int, _ textEncoding: String.Encoding) {
super.init()
Stream.getStreamsToHost(withName: ipAddress, port: port, inputStream: &inp, outputStream: &out)
inp!.open()
out!.open()
print("Connection Established")
}
Basically, I'm trying to initiate a DH key exchange. The Swift client sends their public key, and in return, the server is supposed to send back theirs. It does send, but I'm having trouble reading from the InputStream. First, the server sends the size and only then sends the byte array itself. Server uses DataOutputStream for writing.
Anyone can help me with this?
Thank you very much in advance!
Well , u not send to mach information about what ur problem but I suppose that you want read an php file from sever so there is tow part :
part one reading the php file in the swift part you need to add this code in viewDidload() func :
let URL_USER_data = "https://www.ursite.net/infoinputstream.php"
override func viewDidLoad() {
super.viewDidLoad()
//Sending http post request
Alamofire.request(URL_USER_data , method: .get).responseJSON
{
response in
//printing response
print(response)
//getting the json value from the server
if let result = response.result.value {
//converting it as NSDictionary
let jsonData = result as! NSDictionary
//displaying the message in label
self.bytetext.text = jsonData.value(forKey: "byte") as! String?
self.sizetext.text = jsonData.value(forKey: "size") as! String?
}
}
}
don't forget to import Alamofire at the beginning of ur code.
and the php part "infoinputstream.php" or what ever ur php code supposed to be something like ..
<?php
require_once 'connect.php';
$query1="SELECT* FROM data";
$result1 = mysqli_query($conn, $query1);
while( $row1 = mysqli_fetch_assoc($result1) ){
$$response=$row1['byte'];
$$response=$row1['size'];
}
echo json_encode($response);
?>
Hope it's help ..

C# to Java UTF8 string over TCP

I'm unable to send a UTF-8 string from a C# server to a Java client due to an EOF error in the client. How do I properly configure the C# server? I assume the error lies there because this client works with the Java server shown below.
Java client's receive function does this (this also works if I receive from a Java server, shown below):
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); //The constructor initialises a field, using the socket object.
StringBuilder inputMessage = new StringBuilder();
inputMessage.append((String) dataInputStream.readUTF());
Desired C# server:
static async Task Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Any, 34567);
server.Start();
byte[] bytes = new byte[4096];
byte[] responseBytes;
using (var client = await server.AcceptTcpClientAsync()){
using(var tcpStream = client.GetStream())
{
await tcpStream.ReadAsync(bytes, 0, bytes.Length);
var playerNumber = Encoding.UTF8.GetString(bytes);
Console.WriteLine("Player " + playerNumber + " connected."); //java client to server works.
StringBuilder outputMessage = new StringBuilder("Some output");
responseBytes = Encoding.UTF8.GetBytes(outputMessage.ToString());
await tcpStream.WriteAsync(responseBytes, 0, responseBytes.Length); //This doesn't work...
}
server.Stop();
}
}
The error:
java.io.EOFException
at java.base/java.io.DataInputStream.readFully(DataInputStream.java:201)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:613)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:568)
at Client.Connection.Receive(Connection.java:26)
at Client.Main.lambda$main$0(Main.java:30)
at com.sun.javafx.application.PlatformImpl.lambda$startup$5(PlatformImpl.java:271)
at com.sun.glass.ui.Application.invokeAndWait(Application.java:464)
at com.sun.javafx.tk.quantum.QuantumToolkit.runToolkit(QuantumToolkit.java:366)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$startup$10(QuantumToolkit.java:280)
at com.sun.glass.ui.Application.lambda$run$1(Application.java:153)
Interestingly, a Java server doing this works:
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
StringBuilder outputMessage = new StringBuilder("Some output");
dataOutputStream.writeUTF(outputMessage.toString());
dataOutputStream.flush();
EDIT
This is received from the working Java server. The "bytearr" contains 100 bytes that I am using for my message and 100 bytes that are 0 (they come after my message). The "chararr" correctly sees the first 100 bytes as something meaningful and the last 200 bytes as '\u0000':
This is received form the non-working C# server. It seems to start two bytes in compared to the correct version and also it's "chararr" contains only thousands of '\u0000':
DataInputStream's readUTF reads a special data format, it is not a general purpose method for reading a sequence of UTF-8 bytes. Most notably, it expects an initial sequence of bytes specifying the length of the stream.
I found the answer here. Changing the way the Java client reads to this, works:
byte[] buff = dataInputStream.readAllBytes();
String str = new String(buff, "UTF-8");

Why python socket server accept only 5840 characters in a time? [duplicate]

I made a python "queue" (similar to a JMS protocol) that will receive questions from two Java clients. The python-server will receive the message from one of the Java clients and the second one will read the question and post an answer. The connection and messaging works, the problem comes when a Java client answers with a String of great length.
The response received by python is incomplete! What is worse, the message is cut at a certain number of characters and always at the same length, but, that number is different if someone else hosts the server. (i.e.: friend1 hosts the server, friend2 sends response, length received: 1380chars. Friend2 hosts the server, friend1 posts the answer, length received: 1431chars) This is the server-side python code:
s = socket.socket()
host = socket.gethostname()
# host = "192.168.0.20"
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
# print 'Got connection from', addr
message = c.recv(8192) #Is this length a problem?
# print message
message = message.strip()
ipAddress = addr[0]
I read questions here on StackOverflow, that c.recv() should have no problem with a big number of bytes and our response is somewhere close to 1500 characters. This is the java client:
private void openConnection(){
try {
socket = new Socket(HOST, PORT);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socketPregunta.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
} catch (Exception e) {}
}
public void sendAnswer(String answer) throws IOException{
openConnection();
out.write("PUBLISH-" + answer); //This answer is send incomplete!
out.flush();
closeConnection();
}
Thanks in advance!
From the documentation:
recv(buffersize[, flags]) -> data
Receive up to buffersize bytes from the socket. For the optional
flags argument, see the Unix manual. When no data is available, block
until at least one byte is available or until the remote end is
closed. When the remote end is closed and all data is read, return
the empty string.
So recv() can return fewer bytes than you ask for, which is what's happening in your case. There is discussion of this in the socket howto.
Basically you need to keep calling recv() until you have received a complete message, or the remote peer has closed the connection (signalled by recv() returning an empty string). How you do that depends on your protocol. The options are:
use fixed sized messages
have some kind of delimiter or sentinel to detect end of message
have the client provide the message length as part of the message
have the client close the connection when it has finished sending a message. Obviously it will not be able to receive a response in this case.
Looking at your Java code, option 4 might work for you because it is sending a message and then closing the connection. This code should work:
s = socket.socket()
host = socket.gethostname()
# host = "192.168.0.20"
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
# print 'Got connection from', addr
message = []
chars_remaining = 8192
recv_buf = c.recv(chars_remaining)
while recv_buf:
message.append(recv_buf)
chars_remaining -= len(recv_buf)
if chars_remaining = 0:
print("Exhausted buffer")
break
recv_buf = c.recv(chars_remaining)
# print message
message = ''.join(message).strip()
ipAddress = addr[0]

Sending the length of jSON array though sockets (java to python)

I am trying to connect with a python server (from my colleague), with java. The aim (for now) is to send a json array. We start by sending the length first. It works with an equivalent python client, which I am trying to translate into python.
This is an excerpt from my java code
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
long length = (long) arraytosend.length();
out.print(length);
String arraytosend = new JSONArray(test2).toString();
out.println(new JSONArray(test2).toString());
The python server first reads the length like this (I just copied the relevant commands de):
N_BYTES_MSG_LEN = 8
raw_len = connection.recv(N_BYTES_MSG_LEN)
# here it output 51 as raw_len
try:
msg_len = struct.unpack(MSG_LEN_TYPE, raw_len)[0]
print msg_len
logger.debug('announced message length: {}'.format(msg_len))
except:
logger.warning('could not interpret message length')
return None
# read the incoming message
raw_data = connection.recv(msg_len)
if len(raw_data) < msg_len:
logger.info('lost connection')
return None
After the "51" it immediately goes to lost connection.
The python client code (which I am trying to translate into java), works like this:
try:
raw_data = json.dumps(dict(data=data))
except:
logger.warning('Failed to create a json representation of the data')
return False
# TODO: this could fail for *very* large objects
raw_len = struct.pack('Q', len(raw_data))
try:
connection.sendall(raw_len)
connection.sendall(raw_data)
except Exception:
logger.warning('lost connection while sending data')
raise
Your receiver is assuming the length is expressed in 8 bytes (N_BYTES_MSG_LEN). But you send the long as string. PrintWriter.write(long) is the same as PrintWriter.write(Long.valueof(long).toString). For example if the length is 356 it sends "356". You should lef pad your length first: "00000356".
I found the solution, you have to take into account that java uses. You can do this by changing the server (python) code to:
raw_len = struct.pack('!Q', len(raw_data))
And you can then send it with:
JSONObject request = new JSONObject();
request.append("data", array);
byte[] outBytes = jsonObject.toString().getBytes("UTF-8");
out.writeLong(outBytes.length);

Communication Java(Client) with Python(Server)

I am doing a simple Java Client application which should communicate with Python Server. I can easily send a string to Python Server and print it in console, but when i'm trying to use received string in IFs it never get into IF statement even if it should.
Here is Java Client send msg code
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
if(msgToServer != null){
dataOutputStream.writeUTF("UP");
}
System.out.println(dataInputStream.readLine());
And Python Server code:
import socket
HOST = ''
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
print 'Socket now listening'
conn, addr = s.accept()
print 'Connected to: ' + addr[0] + ':' + str(addr[1])
data = conn.recv(1024)
if data == "UP":
conn.sendall('Works')
else:
conn.sendall('Does not work')
conn.close()
s.close()
print data
So when i send to Python Server "UP" it should send back to Java Client "Works", but i reveive "Does not work" and in Python Server the output data is: "UP"
Why it isn't go into if statement?
The JavaDoc of DataOutputStream#writeUTF(...) says:
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow
In you python code your data value will be prefixed with two bytes for the length of the string to follow.

Categories

Resources