I have a slight problem, I have a TCP class which connects to a server, transfers data then closes, this all works well except for if I connect, then stop it, it works, if I keep on doing this, it works, but on the fifth time the connection hangs without any error and doesn't transfer any data.. I've got no idea how to fix this... This is my TCP class code:
package com.millennium.isynccrm.Classes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.util.Log;
public class TcpClient {
public static boolean connected = false;
private static Socket socket;
private static boolean pause = false;
private static SyncClient syncClient = new SyncClient();
public static int sendCount = 0;
public static int receiveCount = 0;
private static AsyncTask<?, ?, ?> sendAsyncTask;
private static AsyncTask<?, ?, ?> receiveAsyncTask;
public TcpClient() { }
public void send (String line) {
if (!connected) connect();
while (!connected) { }
sendAsyncTask = new SenderThread().execute(line);
}
public void disconnect() {
try {
if(connected == true) {
socket.close();
connected = false;
sendCount = 0;
receiveCount = 0;
if (receiveAsyncTask.getStatus().name().equals("RUNNING")) {
receiveAsyncTask.cancel(true);
}
if (sendAsyncTask.getStatus().name().equals("RUNNING")) {
sendAsyncTask.cancel(true);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void pauseReceivingForTimeInterval(int milliseconds) {
pause = true;
new CountDownTimer(milliseconds, 0) {
public void onTick(long millisUntilFinished) { }
public void onFinish() {
pause = false;
}
}.start();
}
private void connect() {
new Thread(new Runnable() {
public void run() {
try {
if (connected == false) {
socket = new Socket("192.168.1.1", 80);
connected = true;
sendCount = 0;
receiveCount = 0;
try {
if (receiveAsyncTask.getStatus().name().equals("FINISHED")) {
receiveAsyncTask = new RecieverThread().execute("");
} else if (receiveAsyncTask.getStatus().name().equals("RUNNING")) {
receiveAsyncTask.cancel(true);
receiveAsyncTask = new RecieverThread().execute("");
}
} catch (Exception e) { receiveAsyncTask = new RecieverThread().execute(""); }
}
} catch (UnknownHostException e) {
connected = false;
e.printStackTrace();
} catch (IOException e) {
connected = false;
e.printStackTrace();
}
}
}).start();
}
private static PrintWriter output;
private static BufferedReader input = null;
private class RecieverThread extends AsyncTask<String, Void, String> {
protected String doInBackground(String... line) {
while (pause) { }
try {
receiveCount++;
if (receiveCount == 1) input = new BufferedReader(new InputStreamReader(socket.getInputStream()), 8 * 1024);
return input.readLine();
} catch (IOException e) {
Log.d("error", "stop");
}
return "stop";
}
protected void onPostExecute(String result) {
if (result == null) return;
else if (!result.equals("") && !result.equals("stop")) syncClient.recieveMessage(result);
else if (!result.equals("stop")) receiveAsyncTask = new RecieverThread().execute("");
}
}
private class SenderThread extends AsyncTask<String, Void, String> {
protected String doInBackground(String... line) {
while (pause) { }
sendCount++;
if (sendCount == 1) {
try {
output = new PrintWriter(socket.getOutputStream(),true);
} catch(Exception e) { e.printStackTrace(); }
}
String msg = line[0] + "\r\n";
output.print(msg);
output.flush();
return "";
}
protected void onPostExecute(String result) {
}
}
}
As you can see another class sends a line to this class to send to the server, then a Async task sends it and another Async task receives it and passes it onto another class which processes it and so on. On the UI I have a start button which when is pressed turns into a stop button and when stop is pressed it calls the 'disconnect' function in here.
I'm not too sure wherever I have done my RecieverThread AsyncTask is correct, it waits for a line from the socket then passes it on and restarts it self to listen for another line, is this a 'good' way of doing this? Or is it a terrible way (which I imagine it is). To be honest I think this class is very 'messy' and I will more than likely be redoing it.
Any suggestion why I can never send data on the fifth time I connect to the server? (One last note, the server is not to blame here, as we have a iPhone app which does the same thing) (Extra side note.. I'm pretty new to Tcp connections and that sort of stuff, and new to Threading/Async Tasks.) :)
Any help, assistance would be much appreciated (: Thanks!
while (!connected) {}??? that's no way to do asynchronous anything. You are hogging the CPU waiting for something to happen, and preventing it from happening by hogging the CPU. Use a Selector, or do a blocking-mode connect.
Related
I've been struggling lately to find a way to deliver strings through a socket file. I'm planning to create a remote tool(client) to execute things based on the received message(server).
I've searched answers for my problem on google and i found some things and managed to understand things but I also got some problems (i'm new to programming, not yet in college).
I would appreciate any help in this matter
SocketService.java ---- class file = serverside
package socket;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class ServiceSocket {
static ServerSocket myService;
static Socket thesocket;
static Thread socketThread;
public static boolean socketRunning;
public static DataInputStream socketMessage;
public static void initialise(String localhost, int portNumber ){
// make a server socket//////
try {
myService = new ServerSocket(portNumber);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
//////////////////////////////
}
public static void deploySocket(){
socketThread = new Thread() {
public void run(){
// making connection
System.out.println("VVaiting for connection...");
try {
thesocket = myService.accept();
System.out.println("Connection made");
socketRunning = true;
} catch (IOException e) {
e.printStackTrace();
}
////////////////////////////////////
try {
StartBrain();
} catch (IOException e1) {
e1.printStackTrace();
}
if(socketRunning = false) {
try {
thesocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
socketThread.start();
}
public static String getSocketMessage() throws IOException {
try {
socketMessage = new DataInputStream(thesocket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
boolean looprunning = true;
String message = null;
System.out.println("entering loop");
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
System.out.println("Message received from UTF: " + message);
System.out.println("loop exited vvith message");
if(message == null) {
message = "no message";
}
return message;
}
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if(BrainMessage == "command") {
System.out.println("Command EXECUTED HAHA");
} else if(BrainMessage == "taskschedule") {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Main.java ----- class file = serverside
package main;
import socket.ServiceSocket;
public class Main {
public static void main(String[] args) {
ServiceSocket.initialise("localhost", 3535);
ServiceSocket.deploySocket();
}
}
}
Main.java = CLIENT
package mainPackage;
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class Main {
private static Socket clientSocket;
public static void sendMessage(String message) throws IOException, InterruptedException {
DataOutputStream dOut = new DataOutputStream(Main.clientSocket.getOutputStream());
dOut.writeUTF(message);
dOut.flush();
dOut.close();
}
public static void main(String[] args) throws Exception {
// String modifiedSentence;
clientSocket = new Socket("localhost", 3535);
System.out.println("Initializing");
sendMessage("command");
boolean running = true;
while(running) {
TimeUnit.SECONDS.sleep(3);
sendMessage("taskschedule");
}
clientSocket.close();
}
}
main problem
do {
try {
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
} catch (EOFException e) {
}
}while(looprunning);
it doesn't read the string/UTF
It does read it, here:
while (socketMessage.readUTF() != null) {
and then throws it away as you're not assigning the return-value to a variable, and then tries to read another one, here:
message = socketMessage.readUTF();
but the one (first) message you send is already gone.
You have problem in
while (socketMessage.readUTF() != null) {
message = socketMessage.readUTF();
looprunning = false;
}
First call to method readUTF() will block thread and read UTF string from socket, but you discard this value and try read string second time.
If you replace socketMessage.readUTF() != null with looprunning server will log this messages:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
no command received
P.S.
Command is not recognized because use compare objects (string is object) with ==, but you must use equals.
public static void StartBrain() throws IOException {
System.out.println("socket brain started");
String BrainMessage = getSocketMessage();
if (BrainMessage.equals("command")) {
System.out.println("Command EXECUTED HAHA");
} else if (BrainMessage.equals("taskschedule")) {
System.out.println("task scheduled");
} else {
System.out.println("no command received");
}
}
Server log:
VVaiting for connection...
Connection made
socket brain started
entering loop
Message received from UTF: command
loop exited vvith message
Command EXECUTED HAHA
I have this Server class,
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public static ArrayList<String> waiting = new ArrayList<String>();
public static ArrayList<String> playing = new ArrayList<String>();
public static ArrayList<Integer> score = new ArrayList<Integer>();
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(4321);
while (true) {
try {
Socket socket = server.accept();
new EchoThread(socket).start();
} catch (Exception exc) {
exc.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void addClient(String name) {
waiting.add(name);
}
public int getNumClients() {
return waiting.size();
}
public String getClientName(int i) {
return waiting.get(i);
}
public void play() {
int scr = 0;
for (int i = 0; i < 4; i++) {
playing.add(waiting.get(0));
score.add(scr);
waiting.remove(0);
}
}
public boolean checkIfPlaying(String name) {
if (playing.indexOf(name) >= 0) {
return true;
} else {
return false;
}
}
}
and the Thread Class,
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
Server s = new Server();
DataInputStream in = null;
DataOutputStream out = null;
String line;
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
while (true) {
try {
line = in.readLine();
String[] prot = line.split(":");
if (prot[0].equals("/login")) {
s.addClient(prot[1]);
} else if (prot[0].equals("/waiting")) {
if (s.checkIfPlaying(prot[1])) {
out.writeBytes("Playing" + "\r\n");
} else {
if (s.getNumClients() >= 4) {
s.play();
out.writeBytes("Playing" + "\r\n");
} else {
out.writeBytes(s.getNumClients() + "\r\n");
}
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
If the client connect to the server, the name of the client is stored in Server Class Array, waiting.
If the waiting clients is equals to 4, it will remove from the waiting array and put it in playing array.
I would like to make the server send message to the first 4 clients in playing array.
How can I do it?
For your Server Class, I would change your ArrayList< String > for waiting and playing to ArrayList< EchoThread >. This way your Server class is tracking each client object themselves instead of just their names. When you instantiate your EchoThread objects, I would pass the local server object to each EchoThread that way each object knows about the server that instantiated them.
Server Class
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public ArrayList<EchoThread> waiting = new ArrayList<EchoThread>();
public ArrayList<EchoThread> playing = new ArrayList<EchoThread>();
public ArrayList<Integer> score = new ArrayList<Integer>();
public static void main(String[] args) {
try {
// Instantiate a single server object that you can pass into your connected clients
Server myServer = new Server();
ServerSocket server = new ServerSocket(4321);
while (true) {
try {
Socket socket = server.accept();
// Pass myServer into Echo Thread
new EchoThread(myServer, socket).start();
} catch (Exception exc) {
exc.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Have to synchronize this since multiple clients could be adding to this list at the same time
public synchronized void addClient(EchoThread client) {
waiting.add(client);
}
public int getNumClients() {
return waiting.size();
}
public String getClientName(int i) {
return waiting.get(i).getCName();
}
public void play() {
int scr = 0;
for (int i = 0; i < 4; i++) {
EchoThread clientBeingMovedToPlaying = waiting.get(0);
playing.add(clientBeingMovedToPlaying);
score.add(scr);
waiting.remove(0);
// This will be a new method in your EchoThread class
clientBeingMovedToPlaying.SendServerPlayingMessage();
}
}
public boolean checkIfPlaying(String name) {
boolean isPlaying = false;
for(EchoThread client : playing) {
if (client.getName().contentEquals(name)) {
isPlaying = true;
break;
}
}
return isPlaying;
}
}
For your Echo Thread class, I would make your variables in your run method class variables so they can be used throughout the class
EchoThread Class
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class EchoThread extends Thread {
protected Socket socket;
protected Server s;
protected DataInputStream in;
protected DataOutputStream out;
protected String line;
protected String clientName;
// This way, each EchoThread object knows about the server
public EchoThread(Server theServer, Socket clientSocket) {
this.s = theServer;
this.socket = clientSocket;
}
public void run() {
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
while (true) {
try {
line = in.readLine();
String[] prot = line.split(":");
if (prot[0].equals("/login")) {
// Original code
//s.addClient(prot[1]);
// New code
clientName = prot[1];
s.addClient(this);
} else if (prot[0].equals("/waiting")) {
if (s.checkIfPlaying(prot[1])) {
out.writeBytes("Playing" + "\r\n");
} else {
// You don't want multiple clients firing the play method, so you need to synchronize your server object
synchronized (s) {
if (s.getNumClients() >= 4) {
s.play();
out.writeBytes("Playing" + "\r\n");
} else {
out.writeBytes(s.getNumClients() + "\r\n");
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
public String getCName() {
return clientName;
}
public void SendServerPlayingMessage() {
if (out != null) {
// Send whatever message you want
}
}
}
I think this'll get you what your wanting... Forgive any syntax or logical errors, I don't have an IDE right in front of me at the moment.
Hi I am trying to set up a ServerSocket in java and I have kept the backlog level to default 50. I have 5 clients trying to connect to the server at almost the same time. Sometimes everything goes smoothly while sometimes some of the client's connections are refused by the server. I have tried increasing backlog value to 100 but no luck. I am using Ubuntu 13.10. Any ideas?
package networkmodule;
import iomodule.FileHandler;
import java.io.*;
import java.net.*;
import java.util.*;
public class FileReceiveServer implements Runnable {
private ServerSocket server;
private int receiveport;
private boolean isMaster;
private boolean isStats;
private ArrayList<Thread> clientThreads;
private int totalClients;
private int clientsReceived;
public FileReceiveServer(int receiveport, boolean isMaster, boolean isStats) {
this.receiveport = receiveport;
this.isMaster = isMaster;
this.isStats = isStats;
clientThreads = new ArrayList<Thread>();
if (isMaster && !isStats) {
totalClients = ((Hashtable<String, String>) FileHandler.loadObject("clientstats")).size();
clientsReceived = 0;
}
try {
server = new ServerSocket(receiveport);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
Socket clientSocket = server.accept();
Thread newClientThread = new Thread(new FileReceiverThread(clientSocket, isMaster, isStats));
clientThreads.add(newClientThread);
newClientThread.start();
if (isMaster && !isStats) {
clientsReceived++;
}
}
} catch (IOException e) {
}
}
public boolean checkThreadCompletion() {
if (isMaster) {
if (clientsReceived < totalClients) {
return false;
}
if (clientThreads.size() > 0) {
for (Thread t : clientThreads) {
if (t != null) {
if (t.isAlive()) {
return false;
}
}
}
return true;
}
return false;
} else {
if (clientThreads.size() > 0) {
for (Thread t : clientThreads) {
if (t != null) {
if (t.isAlive()) {
return false;
}
}
}
return true;
}
return false;
}
}
public void stopServer() {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is quite a simple code and I have no idea why it fails sometimes. Here the important thing is that it fails only sometimes not always, and when it fails, it always fails on client side when I try to make a socket to connect to the server with:
java.net.ConnectException: Socket Connection Refused
Any ideas?
Thanks
I am using RXTX to communicate between JAVA and a microcontroller.
This is the JAVA code for opening a connection, sending and receiving data
package app;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SerialCommunication1 {
private static SerialCommunication1 instance = null;
private static boolean coonected = false;
public static SerialCommunication1 getInstance(){
if(instance == null)
instance = new SerialCommunication1();
return instance;
}
private SerialCommunication1() {
super();
try {
connect("COM4");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SerialCommunication1.coonected = true;
}
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier
.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPort commPort = portIdentifier.open(this.getClass().getName(),
2000);
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
} else {
System.out
.println("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable {
InputStream in;
public SerialReader(InputStream in) {
this.in = in;
}
public void run() {
byte[] buffer = new byte[1024];
int len = -1;
try {
while ((len = this.in.read(buffer)) > -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And this is the Java code that is calling when an event triggers
SerialCommunication1.getInstance();
if(ledStatus == true) {SerialCommunication1.SerialWriter.str = "4A01";}
else {SerialCommunication1.SerialWriter.str = "4A00";}
stopProcess();
And now the problem. I need to send a command to my microcontroller with the code 4A01 and, after receiving the answer, I need to call it again with the code 4A00. The calls are triggered by a button from my Java interface. The problem is that the second call is not executed (4A00 is not sending). I tried to inverse the command codes and they work well. After the first one (4A01) is executed, my microcontroller reacts and sends the response which is read by java and my interface is updated. When I send the invers command (4A00) it stops exactly at this line SerialCommunication1.SerialWriter.str = "4A00"; and doesn't even enter inside the SerialWriter's run() method.
Do you have any idea why is this happening? From the side of my microcontroller there is no problem, I checked all the possibilities with a tool.
I hope I made myself clear.
Thank you!
LE: I forgot to tel you that it didn't throw any errors or exceptions
I'm not sure because I'm not able to test your code but I think your problem is in SerialWriter class:
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null; // Here str is initialized to null
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0) { // this should throw NPE because str is null
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Since there is no loop in this method, then the thread created within SerialCommunication1 at this line:
(new Thread(new SerialWriter(out))).start();
most likely finishes its execution after sending the first str.
Honestly I don't understand how does it even send a single string, since str is initialized to null in first place and it should throw NullPointerException at str.length() line.
I would suggest you this approach:
Don't trigger a writer thread when connection is established, just trigger a new one every time a message will be sent.
Use Singleton pattern correctly.
Keep a reference to the serial port in SerialCommunication1 class.
Translated to code it would be something like this:
class SerialWriter implements Runnable {
OutputStream out;
String message;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void setMessage(String msg) {
this.message = msg;
}
public void run() {
try {
if(message != null) {
this.out.write(str.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then in SerialCommunication1 class add this public method:
public void sendMessage(String msg) {
SerialWriter writer = new SerialWriter(serialPort.getOutputStream()); // of course you'll have to keep reference to serialPort when connection is established
writer.setMessage(msg);
(new Thread(writer)).start();
}
And finally call this method in this way:
SerialCommunication1.getInstance().sendMessage("4A01");
tzortzik,
I think tha is a timeout problem. Try to addding a delay to writer :
/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
Thread.sleep(500); //<----------- this should be in mainThread before to SerialWriter.start();
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It happens to me many times, "we should learn to wait for a response" (^_^)
Check if you are executing well a secuence like the next:
Send command 4A01
Receive response 4A01 from micro
WAIT FOR RESPONSE BEFORE SEND SECOND COMMAND. Thread.sleep(500); //wait for 500 milis or more
Send command 4A00
Receive response 4A00 from micro
I hope it could help you.
Before people suspect that I have no idea what I'm doing at all (and end up voting this down for no reason at all), please read this:
It connects to my server just fine! I'm getting no errors (from the client OR server), and my server is recognizing the connection. It works with my friend's client that he made, but I wanted to make my own client, and apparently I'm doing something wrong. PLEASE STAY ON TOPIC! Thanks :)
Title basically says it all. I've tested with println messages above and below the setupStream() in my Client.java run(), but only the message above the setupStream() prints. I'm not sure how I'm supposed to initialize my stream without making my program come to a halt.
Client.java
import java.io.IOException;
public class Client extends Stream implements Runnable {
public boolean running = false;
private Thread clientThread;
Frame frame;
public Client() {
super("localhost", 43594);
frame = new ClientFrame(500, 500);
start();
}
public synchronized void start() {
if(running) return;
running = true;
clientThread = new Thread(this);
clientThread.start();
}
public synchronized void stop() {
if(!running) return;
running = false;
clientThread.interrupt();
try {
clientThread.join();
} catch (InterruptedException e) {e.printStackTrace();}
}
public void run() {
try{
setupStream();
while(running) {
System.out.println("running");
}
}catch(IOException e) {
e.printStackTrace();
}finally {
try{
out.close();
in.close();
socket.close();
clientThread.join();
}catch(IOException | InterruptedException e) { e.printStackTrace(); }
}
}
public static void main(String[] args) {
new Client();
}
}
Stream.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Stream {
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
String data;
public Stream(String host, int port) {
try {
socket = new Socket(host, port);
} catch (IOException e) {
e.printStackTrace();
}
}
protected void setupStream() throws IOException {
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());
}
}
My Server Thread:
package Server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
public class User extends Thread {
public static int users = 0;
public int ID;
public String username;
boolean online = false;
public static ArrayList<String> usernames = new ArrayList<String>();
Socket socket;
DataOutputStream out;
DataInputStream in;
String input;
public User(Socket socket) {
this.socket = socket;
}
public String decode(String input) {
String[] split = input.split(" ");
if(input.startsWith("::")) {
try {
switch(split[0].substring(2, split[0].length()).toLowerCase()) {
case "setname":
case "changename":
case "newname":
if(usernames.contains(split[1].toLowerCase())) {
out.writeUTF("This name is already taken! Please choose a different one.");
out.flush();
return null;
}
if(username == null) {
username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
Server.users.put(split[1].toLowerCase(), Server.user[ID]);
usernames.add(split[1].toLowerCase());
} else {
usernames.remove(username.toLowerCase());
username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
usernames.add(split[1].toLowerCase());
}
return null;
case "rank+":
return null;
case "[sm]=":
return null;
}
}catch(IOException e) { }
}
return input;
}
String timeStamp;
public void run() {
try {
out = new DataOutputStream(socket.getOutputStream());
out.flush();
in = new DataInputStream(socket.getInputStream());
while((input = in.readUTF()) != null) {
input = decode(input);
if(input != null) {
if(username != null) {
timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
Server.sendGlobalMessage(timeStamp + username +": "+input);
} else {
timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
Server.sendGlobalMessage(timeStamp + "Guest "+ID+": "+input);
}
}
}
}catch(IOException e) { e.printStackTrace(); } finally {
try{
out.close();
in.close();
socket.close();
} catch(IOException e) { e.printStackTrace(); }
}
}
}
I haven't touched the code of my Server Thread for a while, since it has always worked up until I made my new client.
I suspect that your server does not create an ObjectOutputStream, so when the client constructs its ObjectInputStream, it blocks waiting for the object stream header, which never arrives.