i try to connect my windows desktop java server from android client. I'm working cross-platform. Desktop server and desktop client working fine with same code, but desktop server and android client has a interesting problem. manifest permissions is setted.
Desktop java server code
ServerSocket serverSocket = new ServerSocket(tcp_port);
Socket link = null;
while(true) {
link = serverSocket.accept();
PrintWriter output = new PrintWriter(link.getOutputStream(),true); // flush true
BufferedReader input = new BufferedReader(new InputStreamReader(link.getInputStream()));
// step 1 password auth
String message = input.readLine(); // wait password
if(message.equals(password)) {
output.println("correct");
message = null;
message = input.readLine(); // wait udp port request
if(message.equals("UDP")) {
output.println(udp_port+"");
etc
.
.
Android client code
Socket link = null;
link = new Socket(hostip,tcp_port);
PrintWriter output = new PrintWriter(link.getOutputStream(),true); // auto flush true
BufferedReader input = new BufferedReader(new InputStreamReader(link.getInputStream()));
while(true) {
// step1 send the password wait the response
output.println(password);
String message = input.readLine(); // password response
if(message.equals("correct")) {
output.println("UDP"); // request udp
message = null;
message = input.readLine();
udpport = Integer.parseInt(message);
etc
.
.
My problem is same code works fine on java desktop client and java desktop server but
when i try to connect java desktop server from android client password auth part works fine but
output.println(udp_port+""); send data two times when i looked to the server side it sends empty string firstly and then sends my value what is wrong ?
message = null;
message = input.readLine(); // wait udp port request
if(message.equals("UDP")) {
it reads the empty string and jump the if statement but if i use
message = null;
message = input.readLine(); // read empty string
message = input.readLine(); // read my data
if(message.equals("UDP")) {
statement works
This is expected behavior if you try to read the data before it has been received - something that is more likely to occur when receiving from a remote system, but always a possibility you must allow for.
Your application must wait until a full message has been collected, in this case probably by looping on the readLine() call until you get a non-null message.
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'm trying to send a string from my c client to a Java server, after which the server sends a text file to the client.
This is the part of client code that sends the string.
int n = write(sock_fd,"Ready",5);
if (n < 0)
printf("ERROR writing to socket\n");
recv_file(sock_fd, filename);
And this is the server part of java code:
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from client is " + message);
String FILENAME = "data.txt";
sendFile(socket, "data.txt");
Now I have verified that if I remove the part in the server code where it tries to read the string from c client, the rest of the code works fine and the file is transmitted. But if do not comment the string receiving code, both the server and client keep waiting.
I will be grateful if somebody solves this issue for me.
P.S. I know this question has been asked before but that didn't help me, so I started a new thread.
br.readLine() wants to read a line. The client never sends a newline, so the server is waiting for a newline... forever!
Add a newline to the command sent by the client:
int n = write(sock_fd,"Ready\n", 6);
I developed an application which communicates with server over TCP socket connection. When I tested it on emulator, it worked just fine. I could see all intended data flowing through. But when I run the application on my real device, it connects but not writes. To see what's happening, at server side I printed accepted clients and every received bytes. So it says "new client accepted" but never writes any received bytes which means no data received.
My code on Android application, runs without any exception:
clientSocket = new Socket(host, port);
PrintStream output = new PrintStream(clientSocket.getOutputStream());
clientSocket.getOutputStream().write(new byte[]{67,68,75}); //just some random stuff
clientSocket.getOutputStream().flush(); //neither this ...
output.print("hello"); //... nor this works
At the server side:
...
Socket clientSocket = server.accept();
DataStreamInput input = new DataInputStream(clientSocket.getInputStream());
System.out.println("New client accepted");
...
StringBuilder sb = new StringBuilder();
char ch = (char)input.readByte();
while (ch != '\0') {
System.out.println("BYTE received: "+ch); //should print sth no matter what, but doesn't
sb.append(ch);
ch = (char)client.getInput().readByte();
}
String data = sb.toString().trim();
dataReceived(data);
I don't understand why it works with the emulator but not with my device. (Samsung GT-I9500 btw) What could be the problem behind not sending or being unable to send the bytes? Any idea or any kind of help is appreciated. Thanks...
Edit: Something interesting happened. When I print something to output later in a different thread, it sends all of them with previous data.
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");
try {
Scanner inConsole = new Scanner(System.in);
String CONNECT_TO_WHOM = "";
Socket clientEndPoint = new Socket("localhost", 9000);
PrintWriter out = new PrintWriter(clientEndPoint.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientEndPoint.getInputStream()));
MessageFromServerThread messageFromServer = new MessageFromServerThread(in);
messageFromServer.start();
// Giving Client Details To whom To Connect
if(!in.ready())
CONNECT_TO_WHOM = inConsole.nextLine();
//System.out.println("You are Connecting To This " + CONNECT_TO_WHOM);
out.println(CONNECT_TO_WHOM);
//break;
System.out.println("To quit press q");
//inConsole.nextLine();
while(!clientMessage.equals("q")) {
out.println(clientMessage = inConsole.nextLine());
//System.out.println(in.readLine());
}
System.out.println("Check in chatClient");
} catch(Exception e) {
e.printStackTrace();
}
The code working flow:
Whenever client gets connected it the server, server will inform the client about all the other available clients, Then the from the client, server expects to which client to connect.
Here, there is a possibility that the client can be connected to another client before he wants to communicate with others. In that case the server informs that you are connected to Client X. I want to check this incident occurrence, via the if(!in.ready()).
I do understand that the in buffer could very well be empty. any way to effectively do this checking.
The java.io.BufferedReader.ready() method informs whether the stream
is ready to be read. A buffered character stream is only ready when
the buffer is not empty or if the underlying stream is ready.
So your buffer should be empty to make it return false condition