I have a Java Server and one(or more) Android Clients. For now I want them to communicate simply with strings. When i write from android I can get the data in Java Server, but when I try to get the answer from server the Android application stop working. The codes is reported below:
Java Server:
public class Server {
private static int port=12346, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
String end = server.getInetAddress().toString();
System.out.println("\n"+end+"\n");
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
public doComms(Socket server) {
this.server=server;
}
#SuppressWarnings("deprecation")
public void run () {
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(server.getOutputStream())),
true);
while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
}
JOptionPane.showMessageDialog(null, input);
out.println("Enviado");
server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
And Android client's code (it's called every time a button is pressed inside onClick method):
public String enviaMensagem(){
String resposta="";
new Thread(new ClientThread()).start();
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(ip, port);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(input.getText().toString());
resposta = dataInputStream.readUTF();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return resposta;
}
You are using an unsorted mixture of readUTF(), writeUTF(), readLine(), etc. They're not all interoperable. Settle on one of them. If you use writeUTF() you must use readUTF() at the other end. If you use readLine() you must write lines at the other end, with a line terminator such as \r\n or \n.
Related
I want to have a Server that is running and receives messages from Clients such as another Java Applications. I am doing this via BufferedReader with an InputStream and as long as i do it a single time it works as expected. The message gets processed by the method and writes the Test Message of the received message on the screen, but if i let it run in a while loop it says -
java.net.SocketException: Connection reset
So once the Server got a message i dont know how to get a second one, or any following one.
My main source code is:
public static void main (String[] args) {
int port = 13337;
BufferedReader msgFromClient = null;
PrintWriter msgToClient = null;
timeDate td = new timeDate(); //Class i did for myself to get time/date
ServerSocket s_socket = null;
try {
s_socket = new ServerSocket(port);
System.out.println("Server startet at "+td.getCurrDate()+" "+td.getCurrTime());
}
catch (IOException ioe) {
System.out.println("Server on Port "+port+" couldnt be created. \nException: "+ioe.getMessage());
}
Socket socket = null;
try {
socket = s_socket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
msgFromClient = utils.createInputStream(socket);
} catch (IOException ioe) {
System.out.println("Creation of an Input Stream failed.\n Exception - "+ioe);
}
try {
msgToClient = utils.createOutputStream(socket);
} catch (IOException ioe) {
System.out.println("Creation of an Output Stream failed.\n Exception - "+ioe);
}
String input = null;
while (true) {
try {
input = msgFromClient.readLine();
} catch (IOException ioe) {
System.out.println(ioe);
}
if(input!=null) {
System.out.println("Jumping out of loop: "+input);
utils.processCode(input);
}
}
The both classes to create the streams look like this:
public static BufferedReader createInputStream (Socket socket) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
return br;
}
public static PrintWriter createOutputStream (Socket socket) throws IOException {
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
return pw;
}
The "processCode" class then simply is a switch.
Socket socket = null;
try {
socket = s_socket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You only accept one Connection an after this you are doing your handling. You need to open an new Thread for every connection
ExecutorService threadLimit = Executors.newFixedThreadPool(10);
while(true) {
Socket s = serverSocket.accept();
treadLimit.submit(new HandleThread(s));
}
I made a simple app works with socket to transfer data between client and server over local network,
Server java codes:
try {
serverSocket = new ServerSocket(8888);
System.out.println("Listening :8888");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
System.out.println("ip: " + socket.getInetAddress());
String message = dataInputStream.readUTF();
// System.out.println("message: " + dataInputStream.readUTF());
try {
JSONObject jObj = new JSONObject(message);
String flag = jObj.getString("flag");
if (flag.equals("request")) {
String request = jObj.getString("request");
if (request.equals("getGroup"))
dataOutputStream.writeUTF(getGroup());
else if (request.equals("getFood")) {
String groupID = jObj.getString("groupID");
dataOutputStream.writeUTF(getFood(groupID));
}
}
} catch (JSONException | IOException e) {
e.printStackTrace();
}
// dataOutputStream.writeUTF("Hello!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and android client codes:
class Load extends AsyncTask<String, String, String> {
String response;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket("192.168.1.106", 8888);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(utils.getGroup());
response = dataInputStream.readUTF();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
protected void onPostExecute(String file_url) {
showGroup(response);
}
}
How many clients this can handle?
Is there a better solution?
How many clients this can handle?
Basically your code is an iterative server. There’s one big loop, and in each pass through the loop a single connection is completely processed.
A: So in this sense it can handle only one client at a time.
If you want to suport more than one client at a time your server should service multiple clients simultaneously through the use of threads (one thread per each client connection).
The basic flow of logic in such a server is this:
while (true) {
accept a connection;
create a thread to deal with the client;
}
Please refer to the following tutorial for a full explanation and even some code example.
Is there a better solution?
In the Android side, as pointed out in my comment based in the answer here. Using AsyncTask for HTTP communications can have some drawbacks like:
You cannot cancel a request during execution.
The patterns of using AsyncTask also commonly leak a reference to an Activity...
A: A library like OkHttp can apply as a more robust alternative.
I have created a chat server which is multi threaded and as and when the clients connect it initiates a separate thread for them to communicate. The problem is the my server is not broadcasting messages received from one client to all the other clients connected and I simply do not know how to implement it.
Following is my code, feel free to edit:
The serverclass:
ArrayList<ServerThread> clientlist = new ArrayList();
Hashtable clientList = new Hashtable();
private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
public ChatServer(JTextField jtfA, JTextField jtfB, JTextArea jtaA, JTextArea tapane3) {
// TODO Auto-generated constructor stub
address= jtfA;
GETPORT=jtfB;
PORT=Integer.parseInt(jtfB.getText());
displaytext=jtaA;
clientside=tapane3;
}
public void run() {
// TODO Auto-generated method stub
try {
InetAddress ad=InetAddress.getLocalHost();
String ip=ad.toString();
address.setText(string);
address.setEditable(false);
System.out.println("Server IP is: " + ad);
ss = new ServerSocket (PORT);
Socket cs = null;
while (true)
{
cs=ss.accept();
System.out.println("Connected"+clientlist);
ServerThread handler = new ServerThread(cs,displaytext,clientside,writers);
clientlist.add(handler);
handler.start();
System.out.println(writers);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("DisConnect"))
{
try {
ss.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
The server thread class::
public class ServerThread extends Thread {
Socket client;
JTextArea display;
JTextArea clients;
ServerSocket server;
ArrayList<PrintWriter> writers ;
public ServerThread(Socket cs, JTextArea displaytext, JTextArea clientside, ArrayList<PrintWriter> writers) {
// TODO Auto-generated constructor stub
client=cs;
display=displaytext;
clients=clientside;
this. writers=writers;
}
public void run () {
try{
BufferedReader br = new BufferedReader(
new InputStreamReader(
client.getInputStream()));
PrintWriter pr = new PrintWriter(
new OutputStreamWriter(
client.getOutputStream()));
String clientMsg="";
boolean all;
do {
//read msg from client
clientMsg = br.readLine();
//display.setText(clientMsg);
System.out.println("Server Received: " + clientMsg);
pr.println(clientMsg);
display.append(clientMsg+"\n");
clients.append(clientMsg+"\n");
pr.flush();
} while((all=br.readLine() != null));
br.close();
pr.close();
while (true) {
String input = br.readLine();
if (input == null) {
return;
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + ": " + input);
}
}}
catch (UnknownHostException uhe){
System.out.println("Server issue");
}
catch (IOException ioe){
System.out.println("Server Error IO");
}
catch (Exception e){
System.out.println("Server Error General");
}}
}
Faulty do/while loop. You're throwing away every second line, and not detecting end of stream correctly. It should be:
while ((line = br.readLine()) != null)
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.
When ever I run the client after running the server, the server crashes with the error connection reset... here is my code:
initiate a client socket and connect to the server. wait for an input.
Client:
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private String fromServer,fromUser;
public ClientTest() {
try {
socket = new Socket("127.0.0.1", 25565);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
try {
while ((fromServer = in.readLine()) != null) {
System.out.println(fromServer);
out.println("1");
}
System.out.println("CLOSING");
out.close();
in.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ClientTest();
}
initiate a server socket and send a "2" to client and initiate a conversation
Server:
public ServerTest() {
try {
serverSocket = new ServerSocket(25565);
clientSocket = serverSocket.accept();
}
catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
start();
}
public void start() {
try {
PrintWriter out;
out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in;
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
// initiate conversation with client
out.println("2");
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
out.println("2");
}
System.out.println("Stopping");
out.close();
in.close();
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ServerTest();
}
when ever I run the server everything is fine but when I run the client after that the server crashes with connection reset error.
ClientTest() does not call the start() method. Your client exits immediately after establishing the connection.
Alex's answer is right.
This program also goes to infinite loop. You need to add an exit condition in the while loop of client and server.