Android ServerSocket not sending data to client (client c#, server java) - android

I'm playing around ServerSocket on Android as the server part. I don't understand how it behaves. Here are what I tested :
A1. Instantiates a ServerSocket on Android
A2. ServerSocket sends "hello" to client
A3. Client can read the "hello" and can answer back to ServerSocket
A4. ServerSocket on Android receives the answer from the client
=> That works perfectly
Now I want the client to be the first to send a message to ServerSocket :
B1. Instantiates a ServerSocket on Android
B2. Client sends data to ServerSocket
B3. ServerSocket receives the data from client
B4. IMPOSSIBLE TO REPLY to the client
May that be a possible normal behaviour ?
Thanks
here is the source code
public void startServer()
{
log("startServer");
UUID uuid = UUID.randomUUID();
final String sessionId = uuid.toString().replace("-", "");
log("Session ID = " + sessionId);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (stopServer == false) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(7777);
final Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
String strFromClient = "";
int i = 0;
while (i != -1) {
try {
i = inputStream.read();
if (i != -1)
strFromClient += (char) i;
}catch (Exception e){
break;
}
}
inputStream.close();
OutputStream outputStream = socket.getOutputStream();
String strToClient = "test";
byte[] cArray = strToClient.getBytes();
outputStream.write(cArray);
outputStream.flush();
outputStream.close();
socket.close();
serverSocket.close();
log("end server");
} catch (Exception e) {
//log(e.toString());
}
}
}
});
t.start();
}

Ok I found the solution ! The error was because the C# client was not sending the "-1" value (this is only triggered after closing a stream or stuff like that).
The solution is on the Android side, and the reading of the data from the client is now done as follow :
InputStream inputStream = socket.getInputStream();
String strFromClient = "";
int available = inputStream.available();
Log.d("intelsms", "available from client:" + available);
for (int i=0;i<available;i++){
int c = inputStream.read();
strFromClient+=(char)c;
}
I use the "available()" method in order to know how many bytes are available for reading from the client.
OUF !

Related

Android and Arduino socket

I have created a server and client with Android and Arduino but I have a problem. Android reads only one time. Why? this is my code:
Client Android:
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.240");
socket = new Socket(serverAddr, 8888);
if(socket == null)System.out.println("SOCKET NULL");
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),true);
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
msgFromServer = inFromServer.readLine();
System.out.println(msgFromServer);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket != null) {
System.out.println("STOP SOCKET");
// close socket
}
}
}
}
Arduino Server:
void loop() {
YunClient client = server.accept();
sensorValue = analogRead(sensorPin);
String myString = String(sensorValue);
if (client) {
String command = "none";
command = client.readString();
Serial.println(sensorValue);
client.print(myString+"\n");
}
}
LOGCAT:
07-24 11:44:24.468: D/OpenGLRenderer(19693): Enabling debug mode 0
07-24 11:44:25.363: I/System.out(19693): 121
121 is the value from Arduino. But this is showing only once.
It works only once. I want receive data from the Arduino every second.
Thank you guys!
You need to take the accept out of the loop. otherwise it send a string and wait for another connect from client.
YunClient client = server.accept();
void loop() {
sensorValue = analogRead(sensorPin);
String myString = String(sensorValue);
if (client) {
String command = "none";
command = client.readString();
Serial.println(sensorValue);
client.print(myString+"\n");
}
}
Also, I don't see where the client sends something to the server. Instead of System.out.println should't it be out.println?

why android only receive 2896 bytes on c# tcp socket?

c# Use tcp socket Send message to Android:
string data = "my message....";
byte[] msg = Encoding.UTF8.GetBytes(data);
//for example msg Length is 5210 bytes
client.socket.SendBufferSize = 500000;
socket.Send(msg, msg.Length, SocketFlags.None);
Android receive message from c# server-side:
socket = new Socket(ServerIP, ServerPort);
socket.setReceiveBufferSize(500000);
isReceive = true;
receiveThread = new ReceiveThread(socket);
receiveThread.start();
private class ReceiveThread extends Thread{
private InputStream inStream = null;
ReceiveThread(Socket socket){
inStream = socket.getInputStream();
}
#Override
public void run(){
while(isReceive){
byte[] buffer = new byte[99999];
try {
//only receive 2896 bytes?
int size = inStream.read(buffer);
} catch (IOException e) {
unConnSocket();
}
}
}
}
why the size only receive 2896 bytes?
Your Android code has no way of knowing how many bytes the C# code is sending. inStream.read() is reading only the bytes that are currently available on the socket at that moment. You should have the C# code send the string length before sending the string data, so that the Android code knows how many bytes to expect, eg:
string data = "my message....";
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
int dataLen = IPAddress.HostToNetworkOrder(dataBytes.Length);
byte[] dataLenBytes = BitConverter.GetBytes(dataLen);
socket.Send(dataLenBytes);
socket.Send(dataBytes);
private class ReceiveThread extends Thread
{
private DataInputStream inStream = null;
ReceiveThread(Socket socket)
{
inStream = new DataInputStream(socket.getInputStream());
}
#Override
public void run()
{
while (isReceive)
{
try
{
String s;
int size = inStream.readInt();
if (size > 0)
{
byte[] buffer = new byte[size];
inStream.readFully(buffer);
s = new String(buffer, "UTF-8");
}
else
s = "";
// use s as needed ...
}
catch (IOException e)
{
unConnSocket();
}
}
}
}
Because TCP is a byte stream protocol and isn't obliged to deliver you more than one byte at a time.
You have to loop.
I quote from Linux man recv(2):
The receive calls normally return any data available, up to the requested amount, rather than waiting for receipt of the full amount requested.

Android proxy using sockets

I'm trying to create a proxy in Android and I have to use sockets . I've read many tutorials and came up with following code. Unfortunately browser doesn't seem to get any data and after some time it displays standard web page saying that web page is not available. What might be the cause? Thanks for your help.
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(9902, 0, InetAddress.getByName("localhost"));
} catch (Exception e) {
e.printStackTrace();
}
if (serverSocket != null) {
while (!Thread.currentThread().isInterrupted()) {
try {
Socket socket = serverSocket.accept();
new Thread(new RunnableToReadSocketData(socket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class RunnableToReadSocketData implements Runnable {
private final Socket clientSocket;
public RunnableToReadSocketData(Socket socket) {
this.clientSocket = socket;
}
#Override
public void run() {
Socket serverSocket = null;
try {
InputStream streamFromClient = clientSocket.getInputStream();
PrintWriter streamToClient = new PrintWriter(clientSocket.getOutputStream());
StringWriter writer = new StringWriter();
IOUtils.copy(streamFromClient, writer);
String requestString = writer.toString();
int firstSpace = requestString.indexOf(" ");
int secondSpace = requestString.indexOf(" ", ++firstSpace);
String url = requestString.substring(firstSpace, secondSpace);
Uri uri = Uri.parse(url);
String urlWithoutProtocol = uri.getHost();
System.out.println("==============Reading Socket==============\n" + clientSocket.toString() + "\n" + requestString);
serverSocket = new Socket(urlWithoutProtocol, 80);
PrintWriter streamToServer = new PrintWriter(serverSocket.getOutputStream(), true);
streamToServer.write(requestString);
streamToServer.flush();
InputStream streamFromServer = serverSocket.getInputStream();
StringWriter writerResponse = new StringWriter();
IOUtils.copy(streamFromServer, writerResponse);
String responseString = writerResponse.toString();
System.out.println("==============RECEIVED==============\n" + serverSocket.toString() + "\n" + responseString);
streamToClient.write(responseString);
streamToClient.flush();
streamToClient.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (clientSocket != null) {
clientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You're doing this wrong. After you process the CONNECT command you need to start two threads to copy bytes over the connection, one in each direction. Don't attempt to read the entire request before you send anything; ditto the response. Just copy bytes as you receive them.
When you read EOS on one socket, shutdown the other socket for output and exit that thread. If you've already shutdown the socket you read the EOS from, close both and exit the thread. You need this in case either end does a shutdown, to propagate it properly.
I agree with previous.
The general principle is:
Client connects
Start reading thread
Receive request
Parse destination
Open socket to destination
Forward request
For every Read on the destination socket, do a write on the client socket
For every Read on client socket, do a write on destination socket
If either socket closes (errors), close the other
So, two InputStream's, two OutputStreams, and just ferry data across them.

Can not retrieve data from the socket

I am a beginner in developing the java applications. I'm making a chat application on android. I use a thread to serve the client who comes in, but when the client has connected to the server I can not retrieve the data contained in the socket, but when a client connection is lost, data can be displayed. I use the ReadLine method to read data from the socket.
This is the program code on the server side:
package server;
import java.net.*;
import java.io.*;
import java.util.Vector;
import com.sun.org.apache.bcel.internal.generic.NEW;
public class Server {
public static void main(String[] args)throws IOException, InstantiationException,
IllegalAccessException {
ServerSocket servsocket = null;
Socket sock = null;
byte[] bytebuffer = new byte[512];
try {
System.out.println("SERVER IS RUNNING...");
servsocket = new ServerSocket(28000);
while(true){
sock = servsocket.accept();
System.out.println(servsocket.isBound());
System.out.println("Port "+servsocket+" Ready!!!");
System.out.println("Accept connection requests from " + sock);
System.out.println("From CLIENT "+sock.getInetAddress()+ " and PORT " +
sock.getPort());
ChatThread thread = new ChatThread(sock);
System.out.println("Thread is running");
thread.run();
}
} catch (IOException ioe) {
System.out.println(ioe);
}
finally{
try {
servsocket.close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
}
}
class ChatThread extends Thread{
static Vector<ChatThread> chatthread = new Vector<ChatThread>(10);
private Socket sock;
private BufferedReader in ;
private PrintWriter out;
public ChatThread (Socket socket) throws IOException {
this.sock = socket;
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
byte[] bytebuffer = new byte[512];
int receivemssg;
}
public void run(){
int recvMsgSize;
byte[] bytebuffer = new byte[512];
String readsocket;
try {
readsocket = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Below the display on the server side when the program starts. I tried to send the word "Hello ...." from the client side. Can be seen that the thread is not running.
Server is running...
true
Port ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=28000] Ready!!!
Accept connection requests fromSocket[addr=/172.17.231.254,port=3567,localport=28000]
From CLIENT /172.17.231.254 and PORT 3567
Thread is Running...
When I replace the readline method on a thread with getInputStream the thread can be run from the client and the message can be displayed. This is the code that I enter the thread to replace the readline method that I used before.
public ChatThread (Socket socket) throws IOException {
this.sock = socket;
in = sock.getInputStream();
out = sock.getOutputStream();
byte[] bytebuffer = new byte[512];
int receivemssg;
}
public void run(){
int recvMsgSize;
byte[] bytebuffer = new byte[512];
System.out.println("Thread is Running...");
String masuk = new String(bytebuffer);
System.out.println(bytebuffer);
System.out.println(in.toString());
System.out.println("thread successfully executed !!!");
synchronized (chatthread) {
chatthread.addElement(this);
}
try {
while ((recvMsgSize = in.read(bytebuffer)) != -1) {
out.write(bytebuffer, 0, recvMsgSize);
System.out.println("The length of a character is received and returned "+bytebuffer.length);
}
} catch (IOException e) {
System.out.println(e);
}
}
}
but the next problem is I can not bring up the contents of a socket in a string / text that appears is as follows:
Port ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=28000] Siap!!!
Accept connection requests fromSocket[addr=/172.17.231.254,port=3577,localport=28000]
From CLIENT /172.17.231.254 and PORT 3577
Thread is Running...
[B#7c6768
java.net.SocketInputStream#1690726
thread successfully executed !!!
The length of a character is received and returned 512
Please Help me, thanks :) GBU guys...
See the developer docmentation
public final String readLine ()
Since: API Level 1
Returns a string containing the next line of text available from this stream.
A line is made of zero or more characters followed by '\n', '\r', "\r\n"
or the end of the stream. The string does not include the newline sequence.
readLine() will block and not return until it either sees an end-of-line condition such as a newline character, or the end of the stream is reached, which is probably what happens when the connection is lost.
If you want to use readLine() you need to send "Hello....\n" or otherwise append a terminating character for readLine() to see.

Wifi Chat between android and PC

I was working on a application where i needed to establish a communication between android and PC to transfer some data over wi-fi. I am able to communicate between two PC's over wifi. So code from PC side is ready. I needed a reference to use Wifi from android side. Something similar to bluetooth chat is helpful. I am able to scan Wifi networks present in android but not able to proceed further.
Cheers
This one receives a file
private String ReceiveFile() {
try {
ServerSocket socket = new ServerSocket(port);
socket.setSoTimeout(5000);
Socket os = null;
try {
os = socket.accept();
} catch (SocketTimeoutException t) {
if (!socket.isClosed()) socket.close();
return "TIMEOUT";
}
InputStream bos = os.getInputStream();
FileOutputStream fos = new FileOutputStream(FILENAME);
DataOutputStream bw = new DataOutputStream(fos);
int Total = 0;
byte[] buffer = new byte[4096];
int read;
while (true) {
read = bos.read(buffer);
if (read <= 0) break;
bw.write(buffer, 0, read);
Total = Total + read;
}
if (!socket.isClosed()) socket.close();
return "SUCCESS";
} catch (Exception e) {
e.printStackTrace();
return "FAILURE";
}
}
Without knowing what you trying to achieve it is difficult to be more specific but this snippet receives a short data burst.
DatagramSocket serverSocket = new DatagramSocket(PORTNUMBER);
byte[] receiveData = new byte[50];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.setSoTimeout(5000);
serverSocket.receive(receivePacket);
serverSocket.close();

Categories

Resources