I have created a Java server named server.java using java sockets which accepts a string from a client (client.java) on Android, modifies it and send the modified string to the client [which in my case is an Android app].
When I tried to run both of them, without any error the android app successfully sends the user inputted string to the server. The problem arises when server receives the string, sometimes the server does not provide any output. But if the client is closed (or killed) then server terminal outputs as :
message received from client is: null
request: Message sent to the client : i received message:null
message received from client is: null
request: Message sent to the client : i received message:null
message received from client is: null
request: Message sent to the client : i received message:null
message received from client is: null
request: Message sent to the client : i received message:null
message received from client is: null
request: Message sent to the client : i received message:null
Here is the code for Server.java which runs in a desktop computer:
public class Server {
static Socket socket;
static PrintWriter out;
static BufferedReader in;
static int port = 9999;
public static void main(String[] args) {
String query="blank", returnMessage="Server malfunctioning!";
try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port "+port);
socket = serverSocket.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
while(true) {
try {
query=in.readLine();
System.out.println("message received from client is: "+query);
//Processing the query.
returnMessage="i received message:"+query;
//Sending the response back to the client.
out.print(returnMessage);
System.out.println("request: Message sent to the client : " + returnMessage);
} catch (IOException e) {
e.printStackTrace();
} finally {
out.flush();
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
}
And here is ServerConnect.java which extends AsyncTask:
public class ServerConnect extends AsyncTask<Object, Object, Void> {
String TAG="Server";
String message="empty response";
String ip="EMPTY QUERY";
WebView wb;
TextToSpeech tts;
String host = "192.168.2.3";
int port = 9999;
PrintWriter out;
BufferedReader in;
Socket socket;
ServerConnect(String inp, WebView wbb, TextToSpeech ts) {
ip=inp;
this.wb=wbb;
tts=ts;
}
#Override
protected Void doInBackground(Object... voids) {
Log.d(TAG, "ip value "+ip);
try {
// InetAddress address = InetAddress.getByName(host);
socket = new Socket(host, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
//Send the message to the server
out.print(ip);
//out.flush();
Log.d(TAG, "request: Message sent to the server : " + ip);
message = in.readLine();
Log.d(TAG, "doInBackground: message" + message);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message = "My Brain is not working! Reason is: "+e;
} finally {
in.close();
out.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
Log.d(TAG, "doInBackground: finally block");
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(Void result) {
// wb.getSettings().setJavaScriptEnabled(true);
if(message!=null) {
wb.loadDataWithBaseURL(null, message, "text/html", "utf-8", null);
tts.speak(stripHtml(message), TextToSpeech.QUEUE_FLUSH, null, null);
if (!(pullLinks(stripHtml(message)).equals(""))) {
wb.setWebViewClient(new WebViewClient());
wb.setWebChromeClient(new WebChromeClient() {});
wb.loadUrl(pullLinks(message));
//ip.setText("");
super.onPostExecute(result);
}
} else {
wb.loadDataWithBaseURL(null, "Message is null!", "text/html", "utf-8", null);
tts.speak("Message is null!", TextToSpeech.QUEUE_FLUSH, null, null);
}
}
public String stripHtml(String html) {
return Html.fromHtml(html).toString();
}
private String pullLinks(String text) {
String links="";
String regex = "\\(?\\b(http://|www[.])[-A-Za-z0-9+&##/%?=~_()|!:,.;]*[-A-Za-z0-9+&##/%=~_()|]";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
while(m.find()) {
String urlStr = m.group();
if (urlStr.startsWith("(") && urlStr.endsWith(")"))
urlStr = urlStr.substring(1, urlStr.length() - 1);
links=urlStr;
}
return links;
}
}
readLine() returns null at end of stream, i.e. when the peer has closed the connection. You aren't detecting that case: you are treating the null as data. You need to terminate the read loop when you get the null.
NB UnknownHostException cannot be thrown by either print() or readLine().
Related
My team is trying to build the application that detects the movement of the object and sending those information(JSON) to server(backend using java). I have tried to get JSON data via socket, but it shows this kind of error. I'm using postman to send JSON to test. Another question is using tomcat to get and post data from browser is better than using socket in this scenario?
public class ThreadedEchoServer {
static final int PORT = 5000;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
System.out.println("Client connect...");
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new EchoThread(socket).start();
}
}
}
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream inp = null;
BufferedReader brinp = null;
PrintWriter out = null;
try {
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
// out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
JSONObject json = new JSONObject(line);
System.out.println("Client: " + json.toString());
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
Here is json that I used Postman to post request
{
"id": 963,
"result": "United States",
"cook": 30
}
But I got this error
Client connect...
Exception in thread "Thread-0" org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]
at org.json.JSONTokener.syntaxError(JSONTokener.java:505)
at org.json.JSONObject.<init>(JSONObject.java:215)
at org.json.JSONObject.<init>(JSONObject.java:399)
at EchoThread.run(EchoThread.java:34)
I'm trying to write a Java server so that an Android client can send a string to it, and the server would reply with its own string. The first part of this works, where the client sends a string to the server, but the server sending a message to the does not work: the packet makes it out of the server, but the Android client does not pick it up. Does anyone have suggestions on how to fix this?
This entire process worked previously on a Python server, but I am changing to Java because of library support (Java has better support for NAT traversal)
Server (Java):
public class TCPServer implements Runnable {
private Thread t = null;
#Override
public void run() {
// TODO Auto-generated method stub
String receive;
String response = "1||2||3||4\n";
ServerSocket tcpServer = null;
Socket tcpClient = null;
try {
tcpServer = new ServerSocket(4999);
System.out.println(" TCP open for connections");
while(true) {
tcpClient = tcpServer.accept();
BufferedReader inStream = new BufferedReader(new InputStreamReader(tcpClient.getInputStream()));
receive = inStream.readLine();
System.out.println("Server <<< " + receive);
DataOutputStream outStream = new DataOutputStream(tcpClient.getOutputStream());
outStream.write(response.getBytes("UTF-8"));
outStream.flush();
System.out.println("Server >>> " + response);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IOException: " + e.toString());
} finally {
if (tcpServer != null) {
try {
tcpServer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IOException: " + e.toString());
}
}
if (tcpClient != null) {
try {
tcpClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IOException: " + e.toString());
}
}
}
}
public void start() {
// TODO Auto-generated method stub
if(t == null) {
t = new Thread(this);
t.start();
System.out.println("Start TCP Server");
}
}
}
Client (Android):
public class AsyncTCPSend extends AsyncTask<Void, Void, Void> {
String address = "";
String message = "";
String response = "";
AsyncTCPSend(String addr, String mes) {
address = addr;
message = mes + "\n";
}
#Override
protected Void doInBackground(Void... params) {
Socket socket = null;
try {
socket = new Socket(address, 4999);
socket.getOutputStream().write(message.getBytes());
ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream writeIn = socket.getInputStream();
while((bytesRead = writeIn.read(buffer)) != -1) {
writeBuffer.write(buffer,0,bytesRead);
response += writeBuffer.toString("UTF-8");
}
} catch (UnknownHostException e){
e.printStackTrace();
response = "Unknown HostException: " + e.toString();
System.out.println(response);
} catch (IOException e) {
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
I don't know why you would call an InputStream 'writeIn', but the problem is that the client is reading the socket until end of stream, and the server is never closing the accepted socket, so end of stream never occurs.
i've done a socket programming with client residing on android and server residing on the desktop ....... whenever server is down as we know client lost the connection.....so it undergoes a looping until it connects to server.......
here the problem is in the below code
tabletclient = new Socket(SERVER_IP, TAB_SERVER_PORT);
in the while loop in the case of lost connection.........but when the connection is on it again creates a new object........
can anyone please tell me how to solve this problem..........
In the client side
while(true){
try {
tabletclient = new Socket(SERVER_IP, TAB_SERVER_PORT);
tabletout = new PrintWriter(tabletclient.getOutputStream());
in = new Scanner(tabletclient.getInputStream());
try
{
if((line = in.nextLine())!=null)
{
// my task to be done
}
}catch(Exception d){
System.out.println("Connection from server has lost.........tabletclient.isConnected()----->"+tabletclient.isConnected());
}
} catch (UnknownHostException e) { System.out.println("Entered 2.........");
} catch (IOException e) { System.out.println("Entered 3.........");e.printStackTrace();
}
}
In in the Server side
:
:
private Set <Socket> TABhs=new HashSet<Socket>();
:
:
new Thread(new TABServerThread()).start(); // runs in background
:
:
:
class ServerThread implements Runnable {
private ServerSocket server;
#Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
System.out.println("Server Start the server at port " + SERVER_PORT
+ " and waiting for clients...");
while (true) {
Socket socket = server.accept();
System.out.println("Server Accept socket connection: "
+ socket.getLocalAddress());
new Thread(new ClientHandler(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static PrintWriter out;
class ClientHandler implements Runnable {
private Socket clientSocket;
private Scanner in;
public ClientHandler(Socket clietSocket) {
this.clientSocket = clietSocket;
}
#Override
public void run() {
try {
out = new PrintWriter(clientSocket.getOutputStream());
in = new Scanner(clientSocket.getInputStream());
String line;
System.out.println("ClientHandlerThread Start communication with : "+ clientSocket.getLocalAddress());
try{
while((line = in.nextLine()) != null) {
System.out.println("ClientHandlerThread Client says: " + line);
String dat[]=line.split("#");
String query="insert into table_orders (tableno,kotno, orders,status) values('"+dat[1]+"','"+dat[0]+"','"+dat[2]+"','pending')";
try {
int i= dbGetDet.insertDetails(query);
if(i>0)
{
fillTable();
filtercomboBox();
out.print("success");
out.flush();
for(Socket so:TABhs)
{
PrintWriter ot = new PrintWriter(so.getOutputStream());
ot.println("tableallocation#"+dat[1]);
ot.flush();
}
System.out.println("SENDED 'SUCCESS' TO CLIENT");
}
} catch (Exception ex) {
Logger.getLogger(MYClientclass.class.getName()).log(Level.SEVERE, null, ex);
}
// }
}
}catch(Exception r){}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In the Button click of server
String stat=status_combo.getSelectedItem().toString();
String tables=tableno_combo.getSelectedItem().toString();
String kotno=kotno_combo.getSelectedItem().toString();
if(stat.equals("Processing"))
{
try {
TABhs = new CopyOnWriteArraySet(TABhs);
int soint=1;
System.out.println("TABhs Processing--------------------->"+TABhs.size());
for(Iterator <Socket> it=TABhs.iterator();it.hasNext();)
{
Socket so=it.next();
System.out.println("SEEE SOCKET Processing"+soint+"----->"+so.isClosed());
PrintWriter ot = new PrintWriter(so.getOutputStream());
ot.println("tableupdate#"+tables+"#"+kotno+"#processing");
ot.flush();
JOptionPane.showMessageDialog(rootPane, "<html><body>Table Kot Status Changed to <b>Processing</b></body></html>");
soint++;
}
System.out.println("TABhs Processing--------------------->"+TABhs.size());
}
catch (Exception ex) {
Logger.getLogger(MYClientclass.class.getName()).log(Level.SEVERE, null, ex);
}
}
NOW EACH TIME WHEN BUTTON IS CLICKED THE OUTPUT IS AS GIVEN BELOW
FISRT CLICK
SEEE SOCKET Ready 1----->false
Server Accept socket connection: /192.168.1.74
SEEE SOCKET Ready 2----->false
TABhs--------------------->2
SECOND CLICK
SEEE SOCKET Ready 1----->false
SEEE SOCKET Ready 2----->false
Server Accept socket connection: /192.168.1.74
SEEE SOCKET Ready 3----->false
TABhs--------------------->4
FOURTH CLICK
SEEE SOCKET Ready 1----->false
SEEE SOCKET Ready 2----->false
SEEE SOCKET Ready 3----->false
Server Accept socket connection: /192.168.1.74
SEEE SOCKET Ready 4----->false
TABhs--------------------->5
I think the problem is at the client's side you read a line and then create a new connection.
I think you must keep reading the socket until it's closed or an error occurs.
For example:
while (true)
{
tabletclient = null;
int loop = 0;
// loop until a connection is established
while (tabletclient == null)
{
try
{
tabletclient = new Socket(SERVER_IP, TAB_SERVER_PORT);
}
catch (Exception e)
{
e.printStackTrace();
// set the value to quit when no connection could be established
if (loop++ > 100)
return;
}
}
try
{
tabletout = new PrintWriter(tabletclient.getOutputStream());
in = new Scanner(tabletclient.getInputStream());
// read the socket until it's closed or an error occurs
try
{
while ((line = in.nextLine()) != null)
{
// my task to be done
}
}
catch (Exception d)
{
System.out.println("Connection from server has lost.........tabletclient.isConnected()----->"
+ tabletclient.isConnected());
}
tabletsocket.close();
}
catch (UnknownHostException e)
{
System.out.println("Entered 2.........");
}
catch (IOException e)
{
System.out.println("Entered 3.........");
e.printStackTrace();
}
}
Also, you must close the server side when the transfer from the server to the client is completed.
I am new to java TCP socket. I tried to implement a server and a client. So the server should check input (do something) and send string to client. The client should send string to the server and look for an input string from the server (and do something). Both should loop checking and sending all the time if something new is available.
The client can send data to the server, the server receives it an can display/process this data.
But the data from the server isn't displayed by the client. Can someone tell me why the client isn't receiving the string from the server? Any better ideas to do endless loop? There will be only one client and one server.
while true:
server out------> send String-----> in client
in<----- sent String <------ out
this is the simplified server part:
public class MainActivity extends Activity {
Socket client;
ServerSocket server;
int serverport = 54321;
String inputData = null;
BufferedReader in;
PrintWriter out;
String outputData;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(setupConnection).start();
}
private Runnable setupConnection = new Thread() {
public void run() {
try {
server = new ServerSocket(serverport);
while (true) {
client = server.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
inputData = in.readLine();
InputStream inStream = new ByteArrayInputStream(inputData.getBytes());
in.close();
if (inputData != null) {
System.out.println(TAG + "-----Incoming Message---- " + inputData);
//this is working String is shown
} }
out.write("nothing to do?");
out.flush();
out.close();
}
} catch (SocketException e) {
Log.v(TAG, "SocketException: " + e);
e.printStackTrace();
} catch (IOException e) {
Log.v(TAG, "IOException: " + e);
e.printStackTrace();
}
}
the simplified client looks like this:
public class testClass {
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = null;
String host = "127.0.0.1";
int port = 54321;
PrintWriter out = null;
BufferedReader in = null;
while (true) {
try {
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println(TAG + "Error: " + e);
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.out.println(TAG + "Error: " + e);
System.err.println("Couldn't get I/O for " + "the connection to: localhost.");
System.exit(1);
}
out.println("Hello, is it me you're looking for...");
out.flush();
String input = in.readLine();
System.out.println("Input: " + input);
in.close();
out.close();
}
}
}
If readLine() returns null,the peer has closed the connection, and you must do likewise. And stop reading.
if you want implement this code in android , you faces many problems:
you can find the solution in this link:
Post JSON in android
in the following code may be fix this problem:
HttpPost post = new HttpPost("http://xxxxxx");
DefaultHttpClient httpClient = new DefaultHttpClient();
post.setEntity(new ByteArrayEntity(json.toString().getBytes()));
HttpResponse response = httpClient.execute(post);
return EntityUtils.toString(response.getEntity());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
}
I have a problem with my Java program. It has a socket connection between a server and many client. Here is the server (the part which concerns the problem):
private static ArrayList<ParallelServer> clientConnected = new ArrayList<ParallelServer>();
public Server(int port) {
this.port = port;
if (!startServer())
JOptionPane.showMessageDialog(new JFrame(""),
"Error!", "ERROR!",
JOptionPane.ERROR_MESSAGE);
}
private boolean startServer() {
try {
server = new ServerSocket(port);
loadDatabase();
} catch (IOException ex) {
ex.printStackTrace();
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return true;
}
public void runServer() {
while (true) {
try {
client = server.accept();
ParallelServer pServer = new ParallelServer(client);
clientConnected.add(pServer);
Thread thread = new Thread(pServer);
thread.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void sendBroadcast(String username) throws IOException {
for(int i = 0; i < clientConnected.size(); i++)
clientConnected.get(i).sendAnswer("#change," + username);
}
The parallel server is:
private Socket client;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private PrintWriter printwriter;
public ParallelServer(Socket client) {
this.client = client;
}
public void run() {
try {
inputstreamreader = new InputStreamReader(client.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
printwriter = new PrintWriter(client.getOutputStream(), true);
String lineread = "";
while (client.isConnected()) {
lineread = bufferedreader.readLine();
doCommand(lineread);
}
} catch (UnknownHostException unhe) {
} catch (InterruptedIOException intioe) {
} catch (IOException ioe) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void sendAnswer(String answer) throws IOException {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.println(answer);
printwriter.flush();
}
And here is the client:
private String serverurl = "localhost";
private int serverport = 7777;
private PrintWriter printwriter;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private Socket server;
public Client() {
server = null;
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROE!",JOptionPane.ERROR_MESSAGE);
}
}
public String sendCommand(String command) throws IOException {
if(server == null) {
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROR!",JOptionPane.ERROR_MESSAGE);
}
}
if(server != null) {
printwriter = new PrintWriter(server.getOutputStream(), true);
printwriter.println(command);
printwriter.flush();
inputstreamreader = new InputStreamReader(server.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
return bufferedreader.readLine();
}
else
return "#serverProblem";
}
The program is a simple online game with turns. Players' turns are created with a queue and when a player passes his turn, the server send a broadcast message which say "Now it is 'Player 1' turn." (for instance). My problem is that when a client receive the message, its like it add the answer "Now it is 'Player 1' turn." to the next message it will receive. In my case: when a player passes his turn, he sends "#passTurn,username". The ParallelServer class polls it from the queue, puts it at the bottom of the queue, sends the client "#ok" to tell it that the turn has changed successfully and tells the Server class to send the broadcast message. Then, when the same client will try do do a further action, it will consider "Now it is 'Player 1' turn." as the answer the server has given to it. Instead, I would like that the server and the clients work as always and when the broadcast message is cought, the client is notified without any collateral effect.
What can I do?
Thanks.
Your bi-directional message passing mechanism should look something like this:
Server:
Wait on any client InputStream
if (broadcast)
broadcast_message()
else
process_message()
Client:
Receiving Thread:
Wait on server broadcast
Sending Thread:
Wait on messages to be sent to server from the User Input
This should do the trick :)
Hope it helps. Cheers!