Today I was writing an app (Android) that received strings from a server in Node.js. The socket connection is fine, I can send from Android to Server just fine, but when it comes to receiving from Server, readUTF() is stuck at reading. Here's the Android code to send and receive:
Socket socket = new Socket("10.13.37.129",1337);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", "Tristen");
dataOutputStream.writeUTF(jsonObject.toString());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
System.out.println("Receiving");
final byte[] buffer = {};
dataInputStream.read(buffer);
string = new String(buffer);
System.out.println("Received");
Runnable runnable1 = new Runnable() {
#Override
public void run() {
System.out.println("This is the string: " + string);
System.out.println("This is the buffer: " + buffer.length);
System.out.println("This is the buffer.ToString(): " + buffer.toString());
textView.setText(string);
}
};
runOnUiThread(runnable1);
And this is the server code to send the string:
// Add a 'data' event handler to this instance of socket
clientSocket.on('data', function(data) {
console.log('DATA: ' + data);
clientSocket.write('Hello\n');
clientSocket.write('World\n');
});
Can anyone see what's wrong with it?
readUTF() is for reading strings written by DataOutputStream.writeUTF().. Nothing else. Use read(), BufferedReader.readLine(), etc.
Related
I'm trying to send some commands to Android (client) from VB.NET (server) using sockets. I can connect the client to the server, but I don't know how to receive the commands sent by the server.
Here's a part of my Android code:
public void connect(View v){ //called on button click
SERVER_IP = ip.getText().toString(); //it gets the server's ip from an editText
SERVER_PORT = Integer.parseInt(port.getText().toString()); //and the port too
Toast.makeText(this, "Trying to connect to\n" + SERVER_IP + ":" + SERVER_PORT + "...", Toast.LENGTH_SHORT).show();
new Thread(new Runnable() {
public void run() {
InetAddress serverAddr;
try {
serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVER_PORT); //It establishes the connection with the server
if(socket != null && socket.isConnected()){ //not sure if it is correct
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Here comes the problem, I don't know what to add...
}
} catch (Exception e) {
}
}
}).start();
}
And here's a part of my VB.NET send code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
send(TextBox1.text)
End Sub
Private Sub Send(ByVal command)
Dim temp() As Byte = UTF8.GetBytes(command) 'Is UTF8 right to use for that?
stream.Write(temp, 0, temp.Length)
stream.Flush()
End Sub
Question1: is it right to us UTF8 instead of for example ASCII encoding?
Question2: what would I change in the Android code if it wanted to use a timer that sends a command every second?
Thanks.
To read input from a BufferedReader you need to do something similiar to this:
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while((line = input.readLine()) != null){
// do something with the input here
}
A nice tutorial on sockets is available from oracle in the docs: http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
The default charset on Android is UTF-8 http://developer.android.com/reference/java/nio/charset/Charset.html, so no worries there but you can always send a byte stream from the server onto the client and decode it however you want.
To receive a byte stream you need to do this:
BufferedInputStream input = new BufferedInputStream(socket.getInputStream());
byte[] buffer = new byte[byteCount];
while(input.read(buffer, 0, byteCount) != -1 ){
// do something with the bytes
// for example decode it to string
String decoded = new String(buffer, Charset.forName("UTF-8"));
// keep in mind this string might not be a complete command it's just a decoded byteCount number of bytes
}
As you see it's much easier if you send strings instead of bytes.
If you want to receive input from the server periodically, one of the solutions would be to create a loop which opens a socket, receives input, process it, closes the socket, and then repeats, our you could just keep the loop running endlessly until some command like "STOP" is received.
I am working on a client/server project, the client being Android and the server being C#.
What I am trying to do is the Android app listens on a UDP socket and the C# server sends a message on that port. Android will then receive the message from the reply, and send back a response.
This is the code I have:
public void run()
{
Log.d(TAG, "Heartbeat manager thread starting");
try
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
DatagramSocket socket = new DatagramSocket(HEARTBEAT_PORT);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (!cancelThread)
{
socket.receive(packet);
final String xml = new String(packet.getData(), 0, packet.getLength());
Log.v(TAG, xml);
XmlSettings xmlSettings = new XmlSettings();
xmlSettings.setIndent(true);
XmlWriter writer = new XmlWriter(xmlSettings);
writer.writeStartDocument();
writer.writeStartElement("HeartbeatManager");
writer.writeElementString("Command", Defines.ServerCommands.HeartbeatResponse.toString());
writer.writeEndElement();
buffer = writer.returnXmlOutput().getBytes();
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length);
socket.send(replyPacket);
}
}
catch (SocketException ex)
{
Log.e(TAG, "Socket Exception Occurred: " + ex.toString());
}
catch (IOException ex)
{
Log.e(TAG, "IOException Occurred: " + ex.toString());
}
At the moment it throws an exception when I do the socket.send stating that the destination address is null.
You must set the destination address in the DatagramPacket before sending it.
The constructor you're using (without the address) is just for receiving, not for sending.
In UDP protocol, destination is set in the packet because there is not a connection (like TCP)
So in your code you are telling the socket, which has no concecpt of destination to send a packet without destination, so it'll throw and exception.
InetSocketAddress address = InetSocketAddress("www.google.com", 8080);
DatagramPacket replyPacket = new DatagramPacket(buffer, buffer.length, address);
socket.send(replyPacket);
Situation: : I must either send a parameter to the server, or a serialized object. It can be in any random order.
What I've done: As per this post, I developed a protocol to let the server know what I'm sending just before I actually send it. If its any string, it just goes via PrintWriter.println().
But just before sending a serialized object via ObjectInputStream, I send a PrintWriter.println("O"). So the server knows it must expect a serialized object next.
Problem: I'm getting the StreamCorruptedException, even though I'm using only one instance of ObjectInputStream at the client throughout the socket's life. Should anything be done at the Server end ?
----------------------- EDITED BELOW ---------------------
Client End:
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(thisSocket.getOutputStream())),
true);
if (!sent){
out.println("Dummy");
sent = true;
}
objectOutputStream.flush();
objectOutputStream.reset();
out.println("#SerialO#"); //This param signals the server
//that an object will be sent next.
if(((calcSum) this.obj).getRemotable()){
/*objectOutputStream.flush();
objectOutputStream.reset();*/
Log.i("ENDPOINT", "Sending Serialized data ...");
objectOutputStream.writeObject(this.obj);
objectOutputStream.flush();
objectOutputStream.reset();
// Get the byte array
byte[] byteArray = byteArrayOutputStream.toByteArray();
}
Server End:
while (!Thread.currentThread().isInterrupted()) {
try{
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
// NOW DECLARED AND USED IN UpdateUIThread
//PrintStream out = new PrintStream(socket.getOutputStream());
if(!sent)
{
flg = this.input.readLine().toString();
Log.i("SERVER","SERVER Received False flg as "+flg);
sent = true;
}
else{
flg = this.input.readLine().toString();
System.out.println("SERVER Received flg as "+flg);
if(flg.contains("#SerialO#")){ //Be prepared to
// receive a serilized obj from client
//Log.d("SERVER","Received an object");
CommunicationThread commThread = new CommunicationThread(this.clientSocket,it);
new Thread(commThread).start();
}
else
{
//Log.d("SERVER","Received a parameter "+flg);
executor = Executors.newFixedThreadPool(5);
executor.execute(new updateUIThread(this.clientSocket,flg));
}
}
} catch (IOException e) {
e.printStackTrace();
Log.e("SERVER", "Creation went bad -- "+e.toString());
break;
}
catch (Exception e)
{
Log.d("CLIENT TAG", "Creation went bad -- "+e.toString());
}
}
}
...
public CommunicationThread(Socket clientSocket, Intent it) {
this.clientSocket = clientSocket;
try {
Log.d("SERVER","Inside Server's Comm Thread");
if (mInput==null){
Log.i("SERVER","Receiving very first serialized obj");
mOutput = new ObjectOutputStream(this.clientSocket.getOutputStream());
System.out.println("Inside Server's Comm Thread 2 ");
// EXCEPTION OCCURS IN THE LINE BELOW.
mInput = new ObjectInputStream(new BufferedInputStream(this.clientSocket.getInputStream()));
}
You can't mix streams and readers/writers on the same socket if any of them is buffered. In this situation I would use the object stream for everything.
I am trying to create a server and client application on two android Phone(Nexus 4).One Phone as client and other as server. But at the server side I am getting an error of EOF exception while reading the incoming data and at the client side I am getting IO exception while writing some byte to Socket outputStream. Can someone enlighten me what I am doing wrong?
Client side Code
// Send only one byte to server
while (!Thread.currentThread().isInterrupted()) {
try {
Log.d(TAG,"Entering into the IO exception block");
byte[] image_data = new byte[3];
String send_string = new String(image_data);
// Create a Output Stream to send the bytes back to server
OutputStream out;
out = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
Log.d(TAG,"Created data output Stream");
dos.writeUTF(send_string);
/*
dos.writeInt(image_data.length);
dos.write(image_data, 0, image_data.length);
Log.d(TAG,"Writing the ByteArray into Socket ");
*/
out.close();
dos.flush();
dos.close();
s.close();
} catch (IOException e1) {
Log.d(TAG,"Exception while writing to Socket");
e1.printStackTrace();
}
}
Server side Code : Exception while dis.readFully(ClientByteArray)
if (s == null)
s = ss.accept();
Log.d(TAG,"Socket server is closed " + ss.isClosed() +", Recieved Buffer Size = " + ss.getReceiveBufferSize());
Log.d(TAG,"Accepted Client socket at server");
byte[] ClientByteArray = new byte[ss.getReceiveBufferSize()];
InputStream in;
in = s.getInputStream();
DataInputStream dis = new DataInputStream(in);
dis.readFully(ClientByteArray);
Log.d(TAG,"Data recieved from Client, Bytes = " + ClientByteArray.length);
You are writing with writeUTF(), so you should be reading with readUTF().
Im a newbie in this so please escuse me if i ask dumb questions.
Im trying to make a UDP connection between Eclipse's PC Emulator & a android phone
(or between two android phone devices).
I have a router and the phone connects to the internet thru router's wifi network. The PC is on same network also (direct cable router-PC connection). Im trying to send some text data from Server thread to Client thread but nothing is received/sent. :(
The Server java class (RE-EDITED, Server receives msg. from Client):
public class server implements Runnable
{
// the Server's Port
public static final int SERVERPORT = 6000;
// running Server thread.
public void run()
{
Log.d("redwing","server thread started.");
DatagramSocket serverSocket = null;
try
{
// Open Server Port
serverSocket = new DatagramSocket(server.SERVERPORT);
byte[] receiveData = new byte[32];
byte[] sendData = new byte[32];
// loop until "server_finished" becomes False.
while(createserver.server_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// waiting for the incoming client's message packet
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("server","packet received from client, ETA " + timing.getNow() + " " + renderer.recv); // timing getNow - just returns current system minute & second.
// server is replying to the client back with a message.
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
sendData = new String("server msg").getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
renderer.sent = new String(sendData, 0, sendData.length);
Log.d("server","packet sent to client, ETA " + timing.getNow() + " " + renderer.sent); // timing getNow - just returns current system minute & second.
}
}
// close the socket
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
catch (Exception e)
{
Log.e("server", "Error", e);
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
finally
{
if(serverSocket!=null) serverSocket.close();
serverSocket = null;
}
Log.d("redwing","server thread terminated.");
}
}
and the Client java class (RE-EDITED, Client does not receive msg from Server) :
public class client implements Runnable
{
public static final int CLIENTPORT = 5000;
// running Client thread.
public void run()
{
Log.d("redwing","client thread started.");
DatagramSocket clientSocket = null;
try
{
// getting local address
clientSocket = new DatagramSocket(server.SERVERPORT);
InetAddress IPAddress = InetAddress.getByName("192.168.0.100");
// displaying IP & hostname.
Log.d("client", "IP: " + IPAddress.getHostAddress() + " Name: " + IPAddress.getHostName());
byte[] sendData = new byte[32];
byte[] receiveData = new byte[32];
// Loop until client_finished becomes False.
while(createclient.client_finished)
{
if(renderer.gGL!=null) // ignore me, just a null pointer checker
{
// sending a message to the server
sendData = timing.getNow().getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, client.CLIENTPORT);
clientSocket.send(sendPacket);
renderer.sent = new String(sendData,0,sendData.length);;
Log.d("client","packet sent to server, ETA " + timing.getNow());
// waiting for the server packet message.
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
renderer.recv = new String(receivePacket.getData());
Log.d("client","packet received from server, ETA " + timing.getNow());
}
}
// close the socket
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
catch (Exception e)
{
Log.e("client", "Error", e);
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
finally
{
if(clientSocket!=null) clientSocket.close();
clientSocket = null;
}
Log.d("redwing","client thread terminated.");
}
}
the Permisions are enabled in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<user-permission android:name="android.permission.NETWORK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
I'm running the Server on the android PC Emulator, and the Client on my android Phone.
Both Client & Server threads run just fine but ... the problem is that i dont get any data exchanged between them. The client doesn't receive anyting and the server doesnt receive anything. The packets are sent but nothing received .
What im doing wrong ?
Please help me.
Thank you in advance.
After running your emulator, type it in command prompt - "telnet localhost ", then type "redir add udp:5000:6000". Connect client with port number 5000 and open udp server with port number 6000. Then you can receive client message from udp server.
Take a look for details
clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("<pc ip>"); // instead of "localhost"
public static final String SERVERIP = "127.0.0.1"; // 'Within' the emulator!
public static final int SERVERPORT = 6000;
/* Retrieve the ServerName */
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket socket = new DatagramSocket(SERVERPORT, serverAddr);