ObjectInputStream haults program - java

I am trying to send an ArrayList to a client on an android device. The server says it sent the object however on the android device it hangs. I have read around that when creating an ObjectInputStream, an ObjectOuputStream must be created first and then flushed. I have tried that however this is not working for me. I didn't post the code for getting the clients as its just simply reading from a textfile. The Client class is very basic with few properties such as username, password and friends arraylist of strings. Any help would be much appreciated.
Server:
public class Server {
private static final int port = 9001;
private static final String IPAddr = "xxxxxxxxxxx";
ServerSocket server = null;
ArrayList <Client> users = new ArrayList<Client>();
public Server(){
try{
server = new ServerSocket(port);
System.out.println("connected server on port" + port);
while(true){
System.out.println("waiting for connection my ip add is "+ InetAddress.getLocalHost().getHostAddress());
Socket clientsocket = server.accept();
System.out.println("Connect to client:"+ clientsocket.getInetAddress().getHostName());
ClientThread client = new ClientThread(clientsocket);
client.start();
}
} catch(IOException e) {
System.err.println("Could not listen on port");
}
}
//Thread
public class ClientThread extends Thread {
private Socket sckt = null;
public ClientThread(Socket sckt){
super("ClientThread");
this.sckt = sckt;
}
public void run(){
try{
PrintWriter out = new PrintWriter(sckt.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(sckt.getInputStream()));
ObjectOutputStream objectOutput = new ObjectOutputStream(sckt.getOutputStream());
objectOutput.flush();
String Username = input.readLine();
String Password = input.readLine();
System.out.println("recieved from client: "+ Username);
int ClientIndex = isClient(Username);
if (ClientIndex != -1){
if(users.get(ClientIndex).password.equals(Password)){
//password correct -> send friends
out.println("correct");
out.flush();
System.out.println(Username + " is correct");
LoadClientFriends(Username, ClientIndex);
objectOutput.writeObject(users.get(ClientIndex).Friends);
System.out.println("Friends sent");
} else {
//password incorrect -> retry
out.println("password");
System.out.println(Username + " has wrong password");
}
} else {
//not a registered client
out.println("wrong");
System.out.println(Username + " is not a client");
}
} catch(Exception e){
System.err.println("Couldnt connect to Client socket");
}
}
}
public static void main(String[] args){
Server svr = new Server();
}
}
Client/Android:
public class MainActivity extends ActionBarActivity {
//Varibles
EditText username;
EditText password ;
private static final int port = 9001;
private static final String IPAddr = "xxxxxxx";
//Methods
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
/* Drawable d = getResources().getDrawable(R.drawable.actionbar_background);
getActionBar().setBackgroundDrawable(d);*/
}
public void Login(View view) {
//connect to server
Thread myThread2 = new Thread(Connect);
myThread2.start();
}
public void Register(View view) {
Intent i = new Intent(this, register_screen.class);
startActivity(i);
}
Runnable Connect = new Runnable()
{
public void run()
{
try {
Socket connection = new Socket(IPAddr,port);
BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter output = new PrintWriter(connection.getOutputStream(), true);
//Sent the username a password for verifaction
username = (EditText)findViewById(R.id.edtName);
password = (EditText)findViewById(R.id.edtPassword);
output.println(username.getText().toString());
output.flush();
output.println(password.getText().toString());
output.flush();
//Receive confirmation of client
String res = input.readLine();
if (res.contains("correct")){
ObjectOutputStream objectOutput = new ObjectOutputStream(connection.getOutputStream());
objectOutput.flush();
ObjectInputStream objectInput = new ObjectInputStream(new BufferedInputStream(connection.getInputStream())); //Error Line!
Object object = objectInput.readObject();
ArrayList<String> friends = (ArrayList<String>) object;
Intent intent = new Intent(MainActivity.this,chat_screen.class);
intent.putExtra("Friends", friends);
startActivity(intent);
}else if (res.contains("password")){
Intent i = new Intent(getBaseContext(), MainActivity.class);
startActivity(i);
}else {
}
}catch (Exception e){
}
}
};
}

The error you see is due to multiple output stream format. Stick to either ObjectOutputStream/ObjectInputStream or PrintWriter/BufferedReader. I suggest ObjectOutputStream/ObjectInputStream.
Server code: Use objectOutPut for all writes.
// out.println("correct");
objectOutput.writeUTF("correct");
// Update code for password and wrong too - Use objectOutput.writeUTF("");
Client code: Use just ObjectInputStream instead of BufferedReader
Define the objectInput here instead:
// BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
ObjectInputStream objectInput = new ObjectInputStream(connection.getInputStream());
PrintWriter output = new PrintWriter(connection.getOutputStream(), true);
// Read data as follows:
// String res = input.readLine();
String res = objectInput.readUTF();

Related

Broadcast client message to all clients in a chatroom Java

So I've been making a chatroom based off a single server, where clients can connect and talk in the chatroom. At the moment each client can speak to the server and the server returns what the client has said. But I've been struggling to broadcast a single client message to all clients.
I stored all socket connections in an ArrayList and then created a for loop to iterate through all the connections to echo a single message to all the connected clients. Unfortunately my code is not working and I can't understand why. Here's my code:
Handler code:
public class Handler implements Runnable {
private Socket client;
String message = "";
public Handler(Socket client){
this.client = client;
}
#Override
public void run() {
try{
try{
ChatClient CCG = new ChatClient();
Scanner INPUT = new Scanner(client.getInputStream()); //input data from the server
PrintWriter OUT = new PrintWriter(client.getOutputStream()); //output data from the server
while(true){
if(!INPUT.hasNextLine()){ //if nothings there, end it
return;
}
message = INPUT.nextLine(); //get input
System.out.println("Client HANDLER said: "+ message);
//echo out what the client says to all the users
for(int i=1; i<= ChatServer.ConnectionArray.size(); i++){
Socket TEMP_SOCK = (Socket) ChatServer.ConnectionArray.get(i-1);
PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());
TEMP_OUT.println(message);
TEMP_OUT.flush();
System.out.println("Sent to: " + TEMP_SOCK.getLocalAddress().getHostName()); //displyed in the console
}
}
}finally{
client.close();
}
}catch(Exception X){
X.printStackTrace();
}
}
}
EDIT: Changed client.getOutputStream() to TEMP_SOCK.getOutputStream() but still no luck :/
Server code:
public class ChatServer {
public static ServerSocket server;
public static boolean ServerOn=true;
public static ArrayList<Socket> ConnectionArray = new ArrayList<Socket>(); //holds all the connections so messages can be echoed to all the other users
public static ArrayList<String> CurrentUsers = new ArrayList<String>(); //current users
public static void main(String[] args){
//ExecutorService executor = Executors.newFixedThreadPool(30); //number of clients allowed to join the server
try {
server = new ServerSocket(14001);
System.out.println("Server started!");
System.out.println("Waiting for clients to connect...");
while(true){
try {
//ChatClient chatClient = new ChatClient();
Socket client = server.accept();
ConnectionArray.add(client); //add socket to connection array and allows multiple users to enter server
System.out.println(ConnectionArray);
//CurrentUsers.add(chatClient.user);
//System.out.println("Current users: "+CurrentUsers);
System.out.println("Client connected from: " + client.getLocalAddress().getHostName()); //gets their ip address and local host name
Thread thread = new Thread(new Handler(client));
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Client Code:
public class ChatClient extends javax.swing.JFrame {
Socket sock;
String message;
int port = 14001;
PrintWriter write;
BufferedReader read;
String user;
ArrayList<String> usersOnline = new ArrayList();
InputStreamReader streamreader;
boolean userConnected = false;
public ChatClient() {
initComponents();
}
/*public class Incoming implements Runnable{
public void run(){
try{
sock = new Socket("localhost",14001);
write = new PrintWriter(out);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}*/
public void addUser(){
onlineUsersTextArea.append(user+" \n");
usersOnline.add(user);
System.out.println(usersOnline);
}
/*public void Send(){
String bye = (user + ": :Disconnect");
try{
write.println(bye);
write.flush();
}catch(Exception ex){
chatTextArea.append("Could not send disconnect message. \n");
}
}*/
public void userDisconnected(){
chatTextArea.append(user + " has disconnected.\n");
}
public void Disconnect(){
try{
chatTextArea.append("Disconnected.\n"); // Notify user that they have disconnected
write.flush();
sock.close(); // Closes the socket
System.out.println(user + " has disconnected.");
}catch(Exception e){
chatTextArea.append("Failure to disconnect.\n");
}
userConnected = false;
onlineUsersTextArea.setText(""); // Remove name from online users
usernameInputField.setEditable(true); // Allows a username to be created
}
private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {
if(userConnected == false){
user = usernameInputField.getText();
usernameInputField.setEditable(false);
try{
sock = new Socket("localhost", port);
InputStreamReader sReader = new InputStreamReader(sock.getInputStream());
write = new PrintWriter(sock.getOutputStream());
read = new BufferedReader(sReader);
addUser();
chatTextArea.append(user + " has connected. \n");
write.println(user+" has connected."); // Display username of client when connection is established
write.flush(); // Flushes the stream
userConnected = true;
} catch (IOException ex) {
chatTextArea.append("Failed to connect.\n");
usernameInputField.setEditable(true);
ex.printStackTrace();
}
}else if(userConnected == true){
chatTextArea.append("You are already connected. \n");
}
}
private void disconnectButtonActionPerformed(java.awt.event.ActionEvent evt) {
Disconnect();
userDisconnected();
}
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
String nothing = "";
if((userInputTextArea.getText()).equals(nothing)){
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}else{
try{
chatTextArea.append(user + ": " + userInputTextArea.getText()+" \n");
write.println(user + ": " + userInputTextArea.getText());
write.flush();
}catch(Exception ex){
chatTextArea.append("Message failed to send. \n");
}
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}
private void usernameInputFieldActionPerformed(java.awt.event.ActionEvent evt) {
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ChatClient().setVisible(true);
}
});
}
}
My for loop is in the Handler class. I'm not understanding why the message isn't being sent out to the clients. The TEMP_SOCK (temporary socket) should work (I think) but the server only receives the messages but doesn't echo them.
Any help on how to go about this would be really appreciated! Thank you :)
PrintWriter TEMP_OUT = new PrintWriter(client.getOutputStream()); means you're always sending to the same client, you should use PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());

Sockets - Communication between C# and JAVA Android

I have a JAVA application that is reading a message:
public void onClick(View view)
{
new Thread((new ClientThread())).start();
//Intent i = new Intent(MainActivity.this,Main2Activity.class);
// startActivity(i);
}
//Thread que inicia o socket
class ClientThread implements Runnable
{
#Override
public void run() {
try
{
InetAddress serveradress = InetAddress.getByName(server_IP);
Log.e("TCP","A conetar...");
socket = new Socket(serveradress,PORT);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((mensagem = in.readLine()) != null)
{
mensagem_final += mensagem;
}
txt.setText(mensagem_final);
if(in.readLine() == null)
{
Log.e("TCP","Nao tem mensagens");
}
Log.e("MSG",mensagem);
socket.close();
}
catch (UnknownHostException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
Now I'm trying to create a server in C# and all extra code is freezing when I run the server. And I still cant get the message from C# server.
Servidor servidor = new Servidor();
servidor.server();
class Servidor
{
public void server()
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
TcpListener tcplistener = new TcpListener(IPAddress.Any, 6000);
tcplistener.Start();
TcpClient tcpclient = tcplistener.AcceptTcpClient();
byte[] data = new byte[1024];
NetworkStream ns = tcpclient.GetStream();
string welcome = "Ola";
data = Encoding.ASCII.GetBytes(welcome);
ns.Write(data, 0, data.Length);
}
}
Any help? I use Servidor servidor = new Servidor();
servidor.server(); in another windowsform. This window forms load another windowsforms and should also load the server. But everything on the windowsforms just freezes. Maybe I need threads?
AcceptTcpClient is a blocking call, and it really needs to be handled by something that spawns a new thread each time it succeeds, but for a single instance just try wrapping in a new thread e.g.
Task.Factory.StartNew(() =>
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
TcpListener tcplistener = new TcpListener(IPAddress.Any, 6000);
tcplistener.Start();
TcpClient tcpclient = tcplistener.AcceptTcpClient();
byte[] data = new byte[1024];
NetworkStream ns = tcpclient.GetStream();
string welcome = "Ola";
data = Encoding.ASCII.GetBytes(welcome);
ns.Write(data, 0, data.Length);
});

Java Messaging System

I am creating a Java file send program. Right now I am attempting to implement a chat messaging system.
Here is the code for calling the Server/Client code:
if(host.isSelected()) {
Server server = new Server();
ServerChat serverChat = new ServerChat();
server.Thread();
serverChat.Thread();
}
else if(guest.isSelected()) {
Client client = new Client();
ClientChat clientChat = new ClientChat();
client.Thread();
clientChat.Thread();
}
This calls the code in the following classes: ServerChat
public class ServerChat extends Main implements Runnable {
public static ServerSocket ss;
public static Socket s;
public static DataInputStream dis;
public static DataOutputStream dos;
public void Thread() {
(new Thread(new ServerChat())).start();
}
#Override
public void run() {
String variable = "";
try {
ss = new ServerSocket(1234);
s = ss.accept();
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
while (!variable.equals("exit")) {
variable = dis.readUTF();
chatText.setText(chatText.getText().trim() + "\n Client:\t" + variable);
}
} catch (Exception e) {
}
if (send.isSelected()) {
try {
String messageOut = "";
messageOut = chatText.getText().trim();
dos.writeUTF(messageOut);
} catch (Exception e) {
}
}
}
}
ClientChat code:
public class ClientChat extends Main implements Runnable {
public void Thread() {
(new Thread(new ClientChat())).start();
}
#Override
public void run() {
try {
socket = new Socket("localhost", 1234);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
String variable = "";
while (!variable.equals("exit")) {
variable = dis.readUTF();
chatText.setText(chatText.getText().trim() + "\n Server:\t" + variable);
}
} catch (Exception e) {
}
if (send.isSelected()) {
try {
String messageOut = "";
messageOut = chatText.getText().trim();
dos.writeUTF(messageOut);
} catch (Exception e) {
}
}
}
}
They are able to connect to each other, but the data is not being posted into the text boxes which I have created in the main class. (All the elements needed from main are public).
When I connect (via locahost) I create the server through a new class and open up a new thread
public class Server extends Main implements Runnable {
public ServerSocket welcomeSocket;
public String file;
public DataOutputStream dos;
public DecimalFormat df = new DecimalFormat("##, #00");
public BufferedReader inFromClient;
public void Thread() {
(new Thread(new Server())).start();
}
#Override
public void run() {
try {
InetAddress localaddr = InetAddress.getLocalHost();
chatText.append("Local IP Address : " + localaddr);
chatText.append("Local hostname : " + localaddr.getHostName());
String clientSentence = null;
String capitalizedSentence;
welcomeSocket = new ServerSocket(1234);
String file = "";
DecimalFormat df = new DecimalFormat("##, #00");
while (true) {
Socket connectionSocket = welcomeSocket.accept();
inFromClient
= new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
} catch (Exception e) {
chatText.append("Unable to create server");
chatText.append("Can't detect local host : " + e);
}
}
The Same goes for the Client:
public class Client implements Runnable {
public DataOutputStream dos;
public DataInputStream dis;
public Socket skt;
public StringTokenizer st;
public void Thread() {
try {
dos = new DataOutputStream(skt.getOutputStream());
dis = new DataInputStream(skt.getInputStream());
} catch (Exception e) {
System.out.println(e.getMessage());
}
(new Thread(new Client())).start();
}
#Override
public void run() {
try {
InetAddress localaddr = InetAddress.getLocalHost();
skt = new Socket("localhost", 1234);
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
while (!Thread.currentThread().isInterrupted()) {
String data = dis.readUTF();
st = new StringTokenizer(data);
String CMD = st.nextToken();
JFileChooser open = new JFileChooser();
open.showOpenDialog(null);
File f = open.getSelectedFile();
String fileName = f.getAbsolutePath();
FileInputStream fs = new FileInputStream(fileName);
switch (CMD) {
case "CMD_SENDFILE":
try {
fileName = st.nextToken();
System.out.println("Receiving file...");
String path = System.getProperty("user.home");
File file = new File(path + "/Downloads" + fileName + ".txt");
FileOutputStream fos = new FileOutputStream(path);
InputStream input = skt.getInputStream();
byte[] buffer = new byte[1024];
int count, percent = 1;
while ((count = input.read(buffer)) > 0) {
percent = percent + 1;
fos.write(buffer, 0, count);
}
fos.close();
System.out.println("File was saved: " + path);
} catch (Exception e) {
DataOutputStream eDos = new DataOutputStream(skt.getOutputStream());
System.out.println(e.getMessage());
skt.close();
}
break;
}
}
/*String string = in.readLine();
System.out.println("Incoming: " + string + "\n");
System.out.println("Incoming: " + in.readLine() + "\n");
//in.close();*/
} catch (Exception e) {
System.out.println("Error could not connect\n");
}
}
}
Your main problem is here:
public class ClientChat extends Main implements Runnable {
You're mis-using inheritance. Inheritance is not used so that one instance can share variables with another, which is what you're trying to use it for. Instead it's mainly used to share behaviors. I strongly urge that ClientChat not extend Main but rather has a Main field, one whose public methods it can call.
Your other two problems are lesser problems, but they still will cause you headaches:
You generally want to avoid ignoring exceptions as you're doing. At least have the catch block print the stacktrace: e.printStackTrace();.
You will want to be sure that Swing calls, including calls to setText(...) on text components, be made on the Swing event thread. If you're using a plain vanilla thread, then this can be done via SwingUtilities.invokeLater(new Runnable() {...});. Otherwise consider using a SwingWorker which will help automate this for you with its publish / process method pair.
You've asked:
About inheritance, is there any post I can look at for calling main fields for the ClientChat?
Look up "inheritance vs composition" -- you would be using the latter, composition here, not inheritance.
You would likely want to pass information back and forth between the GUI, or "view" portion of your code, with the chat engine or "model" portion of your code. There are several ways to do that, but usually they'd be connected by some type of "control" class or classes, something known as the "MVC" or "Model-View-Controller" architecture.

Getting data from socket on Android

So I have this really, really strange problem with getting data using socket from server which is working on my PC to Android app. All in local network for now.
It is strange, because I wrote server and client apps (both using sockets) to send and get data and it works really great. I tried to do exactly the same on Android and it gets only first response from server, but not the rest after sending token.
I searched through SO and saw piece of advice that available() method is not right so I changed it and it's still not working as I wish it would.
I think there is something wrong with server-side app or android app works way too fast for server and it sends data after ending transmission on android, but I tried to give it a bit of time and nothing...
This is server app (in general it gets token, lets say "RAM" then it gets output from linux process and sends it straight to android app):
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
public class BLCServer extends Thread{
private ServerSocket serverSocket;
public BLCServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(86400000);
}
public void run() {
while(true) {
try {
String token = "";
System.out.println("Waiting for a client on port: "+serverSocket.getLocalPort());
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
System.out.println("Beginning transmission");
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thanks for connecting to " + server.getLocalSocketAddress() + "Goodbye\n");
while(token != "END") {
token = in.readUTF();
if(token.equals("RAM")) {
Ram ram = new Ram();
List<String> ramData = new ArrayList<>();
ramData = ram.getRamData();
System.out.println("RAM");
System.out.println("ram.size(): " + ramData.size());
out.writeUTF("ramBeginning");
for(String x : ramData) {
System.out.println("Wysyłam do clienta: " + x);
out.writeUTF(""+x);
}
out.writeUTF("ramEnd");
} else if(token.equals("CPU")) {
Cpu cpu = new Cpu();
List<String> cpuData = new ArrayList<>();
cpuData = cpu.getCpuLoad();
System.out.println("CPU");
out.writeUTF("cpuBeginning");
for(String x : cpuData) {
out.writeUTF(x);
}
out.writeUTF("cpuEnd");
} else if(token.equals("STORAGE")) {
Storage storage = new Storage();
List<String> storageData = new ArrayList<>();
storageData = storage.printStorageData();
System.out.println("STORAGE");
out.writeUTF("storageBeginning");
for(String x : storageData) {
out.writeUTF(x);
}
out.writeUTF("storageEnd");
} else if(token.equals("UPTIME")) {
Uptime uptime = new Uptime();
String uptimeData = uptime.getUptime();
System.out.println("UPTIME");
out.writeUTF("uptimeBeginning");
out.writeUTF(uptimeData);
out.writeUTF("uptimeEnd");
} else if(token.equals("TEMPERATURES")) {
out.writeUTF("temperaturesBeginning");
out.writeUTF("temperaturesEnd");
} else if(token.equals("END")) {
break;
} else {
out.writeUTF("Token unknown");
}
}
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
int port = 1984;
try {
Thread t = new BLCServer(port);
t.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
And also there is android main activity:
public class MyActivity extends Activity {
TextView cpuT;
TextView ramT;
TextView uptimeT;
TextView storageT;
List<String> ram = new ArrayList<String>();
List<String> cpu = new ArrayList<String>();
List<String> uptime = new ArrayList<String>();
List<String> storage = new ArrayList<String>();
List<String> temperatures = new ArrayList<String>();
public class NetThread extends AsyncTask<String, Void, Void> {
String dstAddress = "192.168.0.111";
int dstPort = 1984;
#Override
protected Void doInBackground(String... args) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
OutputStream outToServer = socket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = new PushbackInputStream(socket.getInputStream());
DataInputStream in = new DataInputStream(inFromServer);
out.writeUTF("Hello from " + socket.getLocalSocketAddress());
int singleByte;
ramT.setText(in.readUTF());
out.writeUTF("RAM");
while((singleByte = inFromServer.read()) != -1) { // there was code like: while(in.available() > 0) { ... } but someone wrote about it's bad behaviour on SO
ramT.setText(ramT.getText() + "\n" + singleByte);
}
}
out.writeUTF("END");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("WEBSERVICE", "Oncreate wywołane\n");
cpuT = (TextView) findViewById(R.id.displayCpu);
ramT = (TextView) findViewById(R.id.displayRam);
uptimeT = (TextView) findViewById(R.id.displayUptime);
storageT = (TextView) findViewById(R.id.displayStorage);
NetThread netThread = new NetThread();
netThread.execute("RAM", "STORAGE", "UPTIME");
}
}
In addition I paste you client application for pc:
public class BLCClient {
public static void main(String[] args) {
String serverName = "localhost";
int port = 1984;
try {
System.out.println("Connecting to..."+serverName+" on port 1984");
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "+client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
Scanner cin = new Scanner(System.in);
String token = "";
out.writeUTF("Hello from " + client.getLocalSocketAddress());
System.out.println("Server says: "+in.readUTF());
while(true) {
System.out.println("Podaj token ciulu: ");
token = cin.nextLine();
System.out.println("Twój token: " + token);
if(token.equals("END")) {
out.writeUTF(token);
break;
} else {
out.writeUTF(token);
System.out.println(in.readUTF());
System.out.println("IN: " + in.available());
while(in.available() > 0) {
System.out.println(in.readUTF());
}
}
}
client.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
Yes. I'm using part of code from tutorialspoint.com. If you need classes for getting data for ram, cpu, storage, temperatures or uptime processes let me know.
For now I've spent around 4 days trying to figure out what is wrong with my code for android (because servers sends data correctly, I'm 99% sure). Please help me. I'm powerless and I want this app wake to work so so badly right now (Actually I made this work using tomcat server, but I want my own server in here).
Thanks.

Socket programming: Broadcast function sends only to one client

I am creating a program where multiple clients can connect to a server. The message sent by a client will be broadcast to all other client connections on the server.
My problem is that the message is broadcast to only the client it has come from, and I cannot spot the error in my code.
Can anyone help me spot where the problem is or how I could improve the code?Thank you.
EDIT:
public class MsgClient{
private Socket client;
private ObjectInputStream input;
private DataOutputStream output;
private BufferedReader keyboard;
private String cmdInput;
public MsgClient(String name, String server, int port){
try{
client = new Socket(server, port);
DataInputStream sInput = new DataInputStream(client.getInputStream());
output = new DataOutputStream(client.getOutputStream());
input = new ObjectInputStream(client.getInputStream());
keyboard = new BufferedReader(new InputStreamReader(System.in));
output.writeUTF(name);
while(true){
System.out.println("Send a msg to the server: ");
cmdInput = keyboard.readLine();
output.writeUTF(cmdInput);
System.out.println(sInput.readUTF());
}
}
catch (Exception e){
e.printStackTrace();
}
}// end constructor
public static void main(String args[]) throws IOException {
if(args.length != 3)
throw new RuntimeException("Syntax: java MsgClient <username> <servername> <port>");
MsgClient aClient = new MsgClient(args[0], args[1], Integer.parseInt(args[2]));
} // end main
}
public class MsgServer {
public MsgServer(int PORT) throws IOException{
ServerSocket server = new ServerSocket(PORT);
System.out.println("Server Established...");
while(true){
Socket client = server.accept();
DataInputStream input = new DataInputStream(client.getInputStream());
ObjectOutputStream oo = new ObjectOutputStream(client.getOutputStream());
DataOutput output = new DataOutputStream(client.getOutputStream());
System.out.println("New client accepted");
String clientName = input.readUTF();
ClientHandler handler = new ClientHandler(clientName, client); // construct and run thread.
handler.start();
System.out.println("Handler started!");
}//end while
}//end of constructor
public static void main(String args[]) throws IOException {
if(args.length != 1)
throw new RuntimeException("Syntax: java MsgServer requires <PORT> number");
new MsgServer(Integer.parseInt(args[0]));
}
}
public class ClientHandler extends Thread {
Socket client;
DataInputStream din;
DataOutputStream dout;
String name;
String clientMsg;
protected static Vector socketVector = new Vector();
public ClientHandler (String name, Socket client) throws IOException{
this.name = name;
this.client = client;
din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream());
}
// Code run at every start()
public void run(){
try{
socketVector.addElement(this);
clientMsg = din.readUTF(); // inside or outside loop?
while(true){
broadcast( name + " has joined auction on IP " + client.getInetAddress());
broadcast( name + " says: " + clientMsg);
}
} catch(IOException ex){
System.out.println("-- Connection to user lost");
} finally{
socketVector.removeElement(this);
broadcast(name + " has left");
try{
client.close();
}catch (IOException ex){
System.out.println("socket to user already closed?");
}
}
}
Another issue is here, in the MsgClient code:
cmdInput = keyboard.readLine();
output.writeUTF(cmdInput);
System.out.println(sInput.readUTF());
A client will not receive a message until after it has sent one.
Where is the broadcast() method?
You are creating two sets of streams in the server. The accept loop shouldn't create any streams or do any I/O. All that should be done in the thread that handles the connection.
You don't need the ObjectInput/OutputStreams at all here.
When you get any IOException other than a read timeout on a socket you must close it. You should also print out the exception's own message, rather than just making up your own.

Categories

Resources