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 ..
Related
I am trying to send receive data using a Python server and a Java client. First, Java sends a JSON in string to Python Server. After the string received, Python server will send a JSON back to the client. After the client receives the JSON from the server, it again sends a JSON in string to server. (Client sends the same message all the time) This is a recursive process.
ISSUE: After when I execute both Python server and Java, Python server receives the message sent by the Java Client and it sent back the JSON. But in the client side, the message sent by the server didnt receive.
Server.py
import socket
import threading
import json
import numpy
HEADER_INITIAL = 25
PORT = 1234
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
def handle_client(self, conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg = conn.recv(HEADER_INITIAL).decode(FORMAT)
if msg:
print("[DATA] RECEIVED"+ str(msg))
x = {
"Sentence": "This is a value"
}
y = json.dumps(x)
conn.send(y.encode(FORMAT))
conn.send("\n".encode(FORMAT));
conn.close()
Client.java
try (Socket socket = new Socket(Address, Port)) {
InputStream input = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(input);
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
int character;
StringBuilder data = new StringBuilder();
while(true){
Thread.sleep(4000);
String strJson = "{'message':'Hello World'}";
JSONObject jsonObj = new JSONObject(strJson);
writer.println(jsonObj.toString());
while((character = reader.read()) != -1) {
data.append((char) character);
}
System.out.println(data);
}
} catch (UnknownHostException ex) {
System.out.println("Server not found: " + ex.getMessage());
} catch (IOException ex) {
System.out.println("I/O error: " + ex.getMessage());
}
UPDATE
Here is the debug output.
I first started the server and then started client. Initially server receives the {'message':'Hello World'} value which is sent by the client and the server sends back the value of the x variable to the client. Then the server receives nothing from the client, but the client prints the value of x continuously.( System.out.println(data);) I tried to send dynamic values from the server to client, but the client prints only the value which is sent by the server in the first time.
You don't provide any debugging output so it's difficult to be 100% sure this is the entire cause. However, it seems pretty evident that this section of your client code isn't correct:
while((character = reader.read()) != -1) {
data.append((char) character);
}
System.out.println(data);
The server is holding the connection open forever (nothing ever sets connected to false). And so in the loop above, the character returned by reader.read will never be -1 because -1 is only returned at "end of stream". End of stream will only occur when the server closes its socket -- or is otherwise disconnected.
You should add a check for the newline to break out of the read loop:
if (character == '\n')
break;
or you could add it to the while condition:
while ((character = reader.read()) != -1 && character != '\n') {
...
Your code overall lacks appropriate handling of possible exceptional conditions. For example, if the client disconnects, your server will never exit its loop. It will call recv, get back an empty string (signifying "end of file" on the connection), and so will correctly bypass sending a response, but it will then simply go back and execute recv again, get an empty string again, and so forth forever.
Also, your python code makes the implicit assumption that the recv returns exactly the single string that was sent by the client, which is not guaranteed. If the client sends a 20 character string for example, it's possible that the first server recv call returns the first 10 characters, and the next call returns the rest.
(In practice, given the sleep in the client side code, that's unlikely to be a problem in this snippet of code, but one should program defensively because in a real production program, there will inevitably be a race or edge case that will do exactly this and it will cause the client and server to get out of sync and be difficult to debug.)
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);
My problem is that when i send data ( with socket.write()) from the nodejs server to the java client the java client is stuck in the datastream as long as there is no FIN packet( which would be send when i use socket.end() in nodejs) from the server.
My quesiton is now wether there is a way java can read it without the FIN package.
I thought there has to be a way because it works perfectly when you create a client with
the net module of NodeJS.
Server
var server = require("net").Server();
function cl(t){console.log(t)};
server.listen("5022","127.0.0.1", function(req,res){
cl("Server started...");
});
server.on("connection", function(socket){
var ip = socket.remoteAddress;
socket.setEncoding("utf8");
cl("connection --> "+ip);
socket.write("Welcome...");
socket.on("data",function(d){
var data = JSON.stringify(d);
cl("Data arrived "+data);
});
socket.on("end", function(){
cl("end");
})
socket.on("close",function(){
cl("Disconnect --> "+ip+"\n");
})
socket.on("error", function(err){
cl("ERROR "+err);
});
});
Note: So as is said, when i would add socket.end() a FIN packet would be send and the java client gets out of the datastream and returns the data. So at the moment i can send data from the server once in the entire session.
part of Client
Socket sc = new Socket(ip, port);
BufferedReader in = new BufferedReader(new
InputStreamReader(sc.getInputStream()));
DataOutputStream out = new DataOutputStream(sc.getOutputStream());
String input;
while(true)
{
while (!in.ready()) {Thread.sleep(2000);}
input = in.readLine();
System.out.println("Message : " + input);
out.writeUTF(input);
}
Note: Sending data to the server does work from this java client.
in.readLine() is doing just what it says, reading a line, which means it's looking for a newline character to know when to stop reading. So in your node code just append a \n when you .write() so that the Java code can resume. Example: socket.write("Welcome...\n");
I am trying to send a simple message "Hi" to node server where I am using express and socket.io.
Here is how I am initializing my node server
var express = require('express');
var app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
server.listen(9001);
an I am trying to send the message from my java class as
Socket socket=new Socket("192.168.9.132", 9001);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Hi");
socket.close();
I am not getting any console log at the node server end about getting message from socket.
Help how can I achieve this?
socket.io is a websocket, which is a different protocol/implementation than a usual socket. See the net library for TCP sockets.
i am developing an android application wherein i have to send a frame in jpeg format allocated to a BufferedArrayOutputStream (baos variable in code). I convert this baos into a byte array to write into the socket.
On the server side i would like to reconstruct the image in jpeg format. If i write the data received in a variable to a '.jpg' file on the server, on opening the file, it gives an error like "file starting with ffx0 not jpeg format". I think this is because the string variable in python writes the data in the file as a hex string.
The client code is as follows :-
Bitmap memoryImage = Bitmap.createBitmap(rgb, previewSize.width,previewSize.height,Bitmap.Config.ARGB_8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(memoryImage.compress(CompressFormat.JPEG,100, baos)){
try {
if(count==0){
byte [] Finalbaos = baos.toByteArray();
int tempLen = Finalbaos.length;
Log.v("Client","ImageBytes :"+ tempLen);
String dataMeta = Integer.toString(tempLen);
Log.v("Client","Integer Size :"+ dataMeta.length());
PrintWriter tempOut = new PrintWriter(socket.getOutputStream());
if(tempOut!=null){
tempOut.write(dataMeta);
Log.v("Client","data size sent");
tempOut.flush();
}
DataInputStream in = new DataInputStream(socket.getInputStream());
if(in!=null){
Log.v("Client","read buffer created");
String xyz = in.readLine();
String temp = "recvd";
Log.v("Client",xyz);
if(xyz.equals(temp)){
OutputStream out = socket.getOutputStream();
out.write(Finalbaos,0,tempLen);
out.flush();
Log.d("Client", "Client sent message");
}
}
server code:
import socket,thread
import string
import array
host=""
port=54321
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(5)
conn,address=s.accept()
data=""
mylen=0
dataRecv=0
file1 = open("myfile.jpg","w")
totalLength=""
length=conn.recv(1024)
conn.send("recvd")
mylen=int(length)
while dataRecv<mylen:
newData=""
newData=conn.recv(1)
if not newData:
break
data+=newData
dataRecv+=len(newData)
result= array.array('B',data.decode("hex"))
file1.write(result)
file1.close()
print len(data)
conn.close()
s.close()
can anyone let me know how to reconstruct the frame on server either in python or C++
mylen=len(length) doesn't give you the length you're trying to send. it gives you how many bytes were read in the previsous recv. So you get the wrong lenght there.
on your client side, you use String xyz = in.readLine(); which will block until a newline character is encountered. but you never send a '\n' on the server side, instead you go waiting for a response from the client. so you have a deadlock there.
you use data.decode("hex") on your recieved data. unless you do the equivalend of data.encode("hex") in java on the other side, that won't work. it should give you an error if the string is not a valid hex-representation of a binary string.
result is an array.array, which you write to file. file1.write expects a string as argument, it gives you an error if you pass your result object.
so i can't even see why your code works at all, and why there's anything at all in your file.