Socket Client Sends nothing - java

I have a Problem: I have a Socket Client on my Android Phone and a Java Socket Server on my PC. Server -> Android works perfektly, but Android -> Server doesn't work.
This is my sending Method on my Phone:
public void sendMessage(String cmd, String parameter) {
String msg;
if(!parameter.equals(""))
msg = cmd+";"+parameter;
else
msg = cmd+";null";
Log.v(TAG,"Send: "+msg);
DataOutputStream bos;
try {
bos = new DataOutputStream(s.getOutputStream());
bos.write(msg.getBytes("US_ASCII"));
bos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
And this is The receiving on my Server:
#Override
public void run() {
while (isRunning) {
try {
DataInputStream dis = new DataInputStream(s.getInputStream());
String message = dis.readUTF();
System.out.println("#"+this.ID+": Received: "+message);
obs.setID(ID);
obs.proceedMsg(message);
} catch (IOException ex) {
this.isRunning = false;
System.out.println("#"+this.ID+": Closed Instance");
}
}
}
Has anyone an Idea? :)
Thanks

You should use writeUTF on a client side. Your server is expecting UTF as you use readUTF method.
writeUTF writes additional 2 bytes in the beginning which indicate block length. When you use plain write method, you do not supply those bytes and this is the problem.

Related

When we receive packets from an UDP server, why do we have to receive them in a seperate thread?

So my application is a very simple. If you type something through the scanner it sends it over to the server, the server sends it back to client. However, i don't understand why we have to put our code where we handle our receiving packets from the server into a thread?
The code below works fine but if i don't use use multithreading then the application doesn't work. The part where i send packets also stop working. Could you explain why this happens?
public class Client {
private static DatagramSocket socket = null;
public static void main(String[] args) {
System.out.println("Send to server:");
Scanner scanner = new Scanner(System.in);
while (true) {
try {
// port shoudn't be the same as in TCP but the port in the datagram packet must
// be the same!
socket = new DatagramSocket();
} catch (SocketException e1) {
System.out.println("[CLIENT] Unable to initiate DatagramSocket");
}
InetAddress ip = null;
try {
ip = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("[CLIENT] Unable to determine server IP");
}
// must be in a while loop so we can continuously send messages to server
String message = null;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
receive();
}
});
thread.start();
while (scanner.hasNextLine()) {
message = scanner.nextLine();
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);
try {
socket.send(packet);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to send packet to server");
}
}
}
}
private static void receive() {
// receiving from server
byte[] buffer2 = new byte[100];
DatagramPacket ps = new DatagramPacket(buffer2, buffer2.length);
while (true) {
try {
socket.receive(ps);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to receive packets from server.");
}
System.out.println("[SERVER] " + new String(ps.getData()));
}
}
}
If you type something through the scanner it sends it over to the
server, the server sends it back to client.
So the main method runs on the main thread and does some job. The job that you just referenced.
Read some user input plus the following part
while (scanner.hasNextLine()) {
message = scanner.nextLine();
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);
try {
socket.send(packet);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to send packet to server");
}
}
Title: receive packets from an UDP server
You want to receive packets but you don't want to block the user from typing something as input and sending it to the server.
Therefore you need to do 2 jobs simultaneously. AKA multithreading

Problem in establishing connection in HTTPS in proxy server.(CONNECT Method)

I am developing a proxy server based on java. For simple http request, proxy server is working. But for HTTPS Connection, connection gets timed out. Here are the steps I did. I first read one line from input stream and created a socket connecting Server. After that I gave 200 Status to client. After that I asynchronously read and write between Client Socket and Server socket. But currently this isn't working and connection gets timedout and I couldn't debug the problem.
public class ProxyServer extends Thread {
private String host;
private int port;
private ServerSocket serverSocket;
private InputStream proxyToClientIP;
private OutputStream proxyToClientOP;
private InputStream proxyToServerIP;
private OutputStream proxyToServerOP;
private Socket socket;
private Socket socketFromProxyServer;
ProxyServer(ServerSocket serverSocket, Socket socket) {
this.serverSocket = serverSocket;
this.socket = socket;
this.start();
}
public void run() {
processInputRequest();
}
public void processInputRequest() {
try {
proxyToClientIP = socket.getInputStream();
proxyToClientOP = socket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(proxyToClientIP));
String hostDetails = reader.readLine();
System.out.println(hostDetails);
boolean isConnect = false;
//Need to parse request and find req type as GET or CONNECT
//As of now we assume it to be Connect request
if (!isConnect) {
processGetRequest();
} else {
processConnectRequest();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void processConnectRequest() {
//Need to get host name from request. Currently Hardcoded for developing purpose
host = "harish-4072";
port = 8383;
try {
socketFromProxyServer = new Socket(host, port);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(proxyToClientOP));
writer.write("HTTP/1.1 200 Connection established\r\n" + "\r\n");
writer.flush();
proxyToServerOP = socketFromProxyServer.getOutputStream();
proxyToServerIP = socketFromProxyServer.getInputStream();
proxyRequest();
} catch (IOException ex) {
System.out.println(ex);
}
}
public void proxyRequest() {
try {
new Thread() {
#Override
public void run() {
try {
byte[] read = new byte[1024];
int in;
System.out.println("Reading");
while ((in = proxyToClientIP.read(read)) != -1) {
proxyToServerOP.write(read, 0, in);
proxyToServerOP.flush();
}
} catch (SocketException e) {
System.out.println(e);
} catch (IOException ex) {
}
}
}.start();
byte[] reply = new byte[1024];
int out;
System.out.println("Writing");
while ((out = proxyToServerIP.read(reply)) != -1) {
proxyToClientOP.write(reply, 0, out);
proxyToClientOP.flush();
}
} catch (IOException ex) {
}
public void processGetRequest() {
//
}
}
I first read one line from input stream and created a socket connecting Server. ... After that I asynchronously read and write between Client Socket and Server socket.
The problem is that you are reading only a single line while you would need to read the full HTTP request header from the client, i.e. everything up to the end of the request header (\r\n\r\n).
Because you fail to do so the unread parts of the HTTP request are forwarded to the server. But the server is expecting the start of the TLS handshake and these data confuse the server. This might result in hanging or aborting, depending on the content of the data and one the kind of server.

How to stop Java Socket client keeps sending 'null' data?

I created 2 Java programs with sockets in it. I want the client to send continuous data to the server. But after the message sent to the server, the client keeps sending 'null' value to the server (it happens when I close the socket in client program).
Here is my codes:
import ...
public class MainClient {
private Socket serverSock;
private PrintStream clientOutput;
public static void main(String[] args) {
MainClient client = new MainClient();
client.runClient();
}
public void runClient() {
try {
serverSock = new Socket("127.0.0.1",8282);
clientOutput = new PrintStream(serverSock.getOutputStream());
clientOutput.println("Hello, I'm Connected.");
for (int i=0;i<5;i++) {
clientOutput.println(i + "");
clientOutput.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// try {
// serverSock.close(); It will keeps sending 'null' data to the server if I use this line.
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
The Server Side:
public class MainServer {
private ServerSocket serverSocket;
private int listenPort = 8282;
private InputStream inps;
private Socket clientSocket;
private BufferedReader clientInput;
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(clientSocket.isConnected()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
}
}catch(IOException ex) {
ex.printStackTrace();
}finally {
try {
clientSocket.close();
} catch (IOException e) {}
}
}
public static void main(String[] args) {
new MainServer();
}
}
I tried to close the OutputStream on the Client side with clientOutput.close(); but it sends nulls to the server after it sends the 0-4 loop.
To make it stop and avoid the client sends null data, i should not insert the serverSock.close(); on the Client, but it will returns SocketException. I wanted the client to send 'Closed' message after its done.
Summary, the output on the server is:
Client: 0
Client: 1
Client: 2
Client: 3
Client: 4
Client: null
Client: null
//And so on..
I think there is something missing on the Client Program, i guess?
Thank you for the help :)
As the comment noted, the client is not sending a null value.
The isConnected() method does not do what you think it does, namely it does not tell you if the socket is currently "connected" to its peer, at least in the way you think it should. isConnected() becomes true as soon as the socket transitions into the connected state, and stays true thereafter, even after the socket is shutdown. See this discussion and others on stackoverflow.
The correct way to determine if the peer has shutdown the connection is to attempt to read from the socket and then examine the result for evidence of closure. Please read the Javadocs for the method you are using, they will tell you what the various return values mean. For the BufferedReader.readLine() method, it says:
Returns:
A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached
Throws:
IOException - If an I/O error occurs
Thus you need to check for a null return value to detect a normal socket closure, and if you receive an IOException that indicates some kind of network anomaly.
Your MainClient() have no problem.
clientSocket.isConnected() function in MainServer() always check the status of the client and which results an infinite loop, so after the message 'client:4', clientInput.readLine() should return 'null'.
So instead of checking the client socket is connected or not you can check the client socket is closed or not using function 'clientSocket.isClosed()'.
replace the while loop in MainServer() with below code,
while(!clientSocket.isClosed()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
if(clientMsg.equals("Closed")){
clientSocket.close();
// serverSocket.close();
}
}
this will help you to close the client socket at the time of receiving 'Closed' message from server and this avoid the infinite execution of while loop as well as null statement printing.
The code "serverSocket.close()" help you to close the server socket and you can use this at 'MainServer()' if you need to stop the port listening.
typically the code should be something similar
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((clientMsg = clientInput.readLine()) != null) {
if(isTerminationString(clientMsg)) {
break;
}
System.out.println("Client : " + clientMsg);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
}
}
}
boolean isTerminationString(String msg) {
return msg.equals("DONE!");
}
where in isTerminationString you check if the msg is a termination msg, the communication protocol should be shared between the client and the server . i gave the example of sending
a DONE message, but it could more complex than that .
as closing the close method on the socket does not guarantee that the socket on the other part gets closed as well, using the isClosed method might not be effective and results in the same problem you have .

Android TCP socket doesn't receive data

I am using Android app to communicate, send and receive messages through TCP socket with a PC java application on the same LAN. Below is the code of Asynctask i am using in android to send a message and receive a reply from PC:
public class Client extends AsyncTask<Void, Void, Void> {
Context context;
String dstAddress;
int dstPort;
String msg;
Client(Context context, String addr, int port, String msg) {
this.context = context;
dstAddress = addr;
dstPort = port;
this.msg = msg;
}
String reply = "";
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
BufferedWriter dout = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//send request
dout.write(msg);
dout.flush();
dout.close();
//get response
reply = br.readLine();
br.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// DISPLAY REPLY CONTENT
Handler handler = new Handler(context.getMainLooper());
handler.post( new Runnable(){
public void run(){
Toast.makeText(context, "Server reply: " + reply ,Toast.LENGTH_LONG).show();
}
});
}
}
I am displaying the reply of the PC in a toast in onPostExcecute.
Android sends the message through BufferedWriter, while the java app on PC receives it in a BufferedReader. (working fine, and tested)
The PC sends a response throught a BufferedWriter to the android after receiving the message, where the android receives the reply in a BufferedReader as shown: br.readLine(). (HERE is the problem): According to the PC's app debug the reply is sent successfully without any IOExceptions or errors happening, But at the android side the reply string is empty, looks like it received nothing. I really don't know what am I doing wrong, and hope someone can point out to what i am missing.
Below is the server's thread that handles a client socket, the thread runs basically whenever serversocket accepts a socket:
static class clientThread extends Thread {
Socket s = null;
clientThread(Socket s) //constructor
{
this.s = s;
}
#Override
public void run ()
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); //receiving data into a buffered reader
String dataIn = br.readLine(); // reading the buffered data into a string
System.out.println("received: " + dataIn);
//BufferedWriter dout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//dout.write("OK");
//dout.newLine();
PrintWriter dout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);
if(dataIn.equals("Android client"))
{
dout.println("OK");
dout.flush();
System.out.println("OK sent");
}
dout.close();
br.close();
s.close();
}
catch (IOException e)
{ System.out.println("Error occured"); }
}
}
SO to sum up the programs, the android sends the message "Android client" (Which the server receives and prints on the console with no issues), now with the reply, the server sends "OK" with no issues as well, but android side receives nothing.
ALSO, as i mentioned before, if i remove
dout.close();
from android's asynctask after i send the message, the server receives the message ONLY when the program gets terminated, I dont understand why i have to close it in order for the message to be sent successfully.
You are reading lines but you aren't sending lines. Add a line terminator to the message sent by the client, or use BufferedWriter.newLine(); and flush() instead of closing the buffered writer.

Android TCP multicast missing message

I build a TCP multicast chat application using asynctask.
I am also trying to order the message in FIFO and causal order.
However, when I try to send a lot of messages simultaneously for testing, it misses some messages but I can't find the reason.
I have tried as hard as I can to improve the performance of the program because I thought the performance could be the reason. but still having the same issue.
I attached some important part of my code.
Most of all,
private class ServerTask extends AsyncTask<ServerSocket, String, Void> {
#Override
protected Void doInBackground(ServerSocket... sockets){
ServerSocket serverSocket = sockets[0];
Socket socket = new Socket();
try {
while(true) {
socket = serverSocket.accept();
InputStream inputstream = socket.getInputStream();
DataInputStream in = new DataInputStream(new BufferedInputStream(inputstream));
String msg = ""+in.readUTF();
String time = ""+in.readUTF();
String temp = time+"||"+msg;
publishProgress(temp);
in.close();
}} catch (IOException e) {
e.printStackTrace();
} finally{
try {
socket.close();
serverSocket.close();////
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
Here is onProgressUpdate.
protected void onProgressUpdate(String...strings) {
/*
* The following code displays what is received in doInBackground().
*/
String strReceived = strings[0].trim();
TextView remoteTextView = (TextView) findViewById(R.id.textView1);
remoteTextView.append(strReceived + "\t\n");
try {
sequencer(strReceived);
} catch (ParseException e) {
e.printStackTrace();
}
return;
}
}
..
private class ClientTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... msgs) {
Date currentDate= new Date();
Timestamp time = new Timestamp(currentDate.getTime());
Message temp = new Message(myPort, msgs[0], time);////
try {
for(int i = 0; i <= 2; i++) {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(REMOTE_PORTS[i])), 1000);
socket.setTcpNoDelay(true);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream o = new DataOutputStream(new BufferedOutputStream(outputStream));
o.writeUTF(msgs[0]);
o.writeUTF(""+time);
o.flush();////
socket.close();
}
}
catch (UnknownHostException e) {
Log.e(TAG, "ClientTask UnknownHostException");
} catch (IOException e) {
Log.e(TAG, "ClientTask socket IOException");
}
return null;
}
Can you find the part causes the problem?
Sequencing / Queueing /Acknowledgement all these things are part of TCP so it is done by the protocol itself so you do not need to do all those explicitly from your code. There are still some parts of your code that can be improved. Like:
String time = received.split("\\|\\|")[0];
String msgToSend = received.split("\\|\\|")[1];
//Instead of doing this, its better to do this:
String peices[]=received.split("\\|\\|");
String msgToSend=peices[1];
String time=peices[0]
Also you can check if you are receiving all the raw messages and if its during the parsing process the messages are getting lost using a log:
Log.d("RAW_MESSAGE","Message Received: "+temp); //in your doInBackground
If you get all the messages that you send in this log, then there is nothing wrong with the protocol or the sending/receiving process rather there is a problem while you are processing the message. Also for these types of use-cases, try using the Service component rather than AsyncTask.
I hope this helps.
First of all multicast is over UDP, not TCP.
And if you want to create a multicast app, you should use multicastsocket
http://developer.android.com/reference/java/net/MulticastSocket.html

Categories

Resources