I have code which works with one client connection. What I need is ability for the server to handle multiple client requests using multithreaded approach.
I found some solutions, but it's not meet my requirements, like this, or this
Server.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends User {
private Socket clientSocket;
private ServerSocket serverSocket;
public Server() {
super();
}
private void createConnection() {
try {
InetAddress locIP = InetAddress.getByName("127.0.0.1");
serverSocket = new ServerSocket(9999, 0, locIP);
// serverSocket = new ServerSocket(4444, 4444, InetAddress.getByName("192.168.0.101"));
} catch (IOException e) {
System.err.println("Could not listen on port: 9999 ." + e);
System.exit(1);
}
}
private void closeConnection() {
try {
serverSocket.close();
} catch (IOException e) {
System.err.println(e);
}
}
#Override
public void connect() {
createConnection();
//Socket clientSocket=null;
try {
clientSocket = serverSocket.accept();
System.out.println("Client connected! "
+ "IP: "
+ clientSocket.getInetAddress()
+ ", port: "
+ clientSocket.getPort());
} catch (IOException e) {
System.err.println("Accept failed. " + e);
System.exit(1);
}
}
#Override
public void disconnect() {
try {
clientSocket.close();
} catch (IOException e) {
System.err.println(e);
}
closeConnection();
}
#Override
public Socket getSocket() {
return clientSocket;
}
#Override
public String toString() {
return new String("Server");
}
}
Client.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client extends User {
private Socket socket;
public Client() {
super();
}
#Override
public Socket getSocket() {
return socket;
}
#Override
public void connect() {
try {
InetAddress locIP = InetAddress.getByName("127.0.0.1");
// socket = new Socket(9999, 0, locIP);
// socket = new Socket("localhost", 9999); oryginalny
socket = new Socket(locIP, 9999);
} catch (UnknownHostException e) {
System.err.println("The host not found! " + e);
System.exit(1);
} catch (IOException e) {
System.err.println("Can't find connection! " + e);
System.exit(1);
}
}
#Override
public void disconnect() {
try {
socket.close();
} catch (IOException e) {
System.err.println(e);
}
}
#Override
public String toString() {
return new String("Client");
}
}
SendButton.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import javax.swing.JButton;
import javax.swing.JTextPane;
#SuppressWarnings("serial")
public class SendButton extends JButton {
private JTextPane incomingMessages;
private JTextPane messageToSend;
private User user;
public SendButton(User user, JTextPane incomingMessages, JTextPane messageToSend) {
super("Send!");
this.user = user;
this.incomingMessages = incomingMessages;
this.messageToSend = messageToSend;
this.addActionListener(new SendListener());
}
public class Write {
private PrintStream out;
public Write() {
try {
out = new PrintStream(new BufferedOutputStream(
user.getSocket().getOutputStream(), 1024), false);
} catch (IOException e) {
System.err.println(e);
}
}
public void send(String message) {
if (message != null) {
out.println(message);
out.flush();
incomingMessages.setText(new String(incomingMessages.getText() + "\nMe: " + message));
}
}
}
public class SendListener implements ActionListener {
private Write write = new Write();
private String toSend;
#Override
public void actionPerformed(ActionEvent event) {
toSend = messageToSend.getText();
if (toSend != null || event.getActionCommand() == "\n") {
write.send(toSend);
}
messageToSend.setText(new String(""));
}
}
}
You need to create a new Runnable class, whose data members consist of a Socket and its input and output streams. This class is used on the server side. Its run() method is responsible for all I/O to that client. Then your accept() loop just looks like this:
while (true)
{
new Thread(new ConnectionHandler(serverSocket.accept())).start();
}
where ConnectionHandler implements Runnable as above.
simply what you need to do is after accepting the request from the client (Using main thread), then the request pass to a new thread with the client socket and process the request inside the new thread. So the main thread is free to accept new requests.
Related
I wrote this code in java based on sockets and thread pool. The server code runs on its own but when I run the client code after running the server, an exception on the server appears. What could be causing this?
Below is the server class which conatains threads for each new client
package java_40;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//Server Implementation
/**
*
* #author Abdullah
*/
public class Server implements Runnable {
private ArrayList<ConnectionHandler> connections;
private ServerSocket server;
private boolean done;
private ExecutorService pool;
public Server (){
connections = new ArrayList<>();
done = false;
}
#Override
public void run() {
try {
while(!done){
server = new ServerSocket(9999);
pool = Executors.newCachedThreadPool();
Socket client = server.accept();
ConnectionHandler handler = new ConnectionHandler(client);
connections.add(handler);
pool.execute(handler);
}
} catch (IOException ex) {
shutdown();
}
}
public void broadcast(String message){
for(ConnectionHandler ch :connections){
if(ch !=null){
ch.sendMessage(message);
}
}
}
public void shutdown(){
try{
done=true;
if(!server.isClosed()){
server.close();
}
for(ConnectionHandler ch : connections){
ch.shutdown();
}
}catch(IOException e){
// ignore
}
}
class ConnectionHandler implements Runnable{ //handles individual client connection
private final Socket client;
private BufferedReader in;
private PrintWriter out;
private String nickname;
public ConnectionHandler(Socket client){
this.client = client;
}
#Override
public void run() {
if(client != null){
try{
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.println("Enter nickname");
nickname =in.readLine();
System.out.println(nickname+" connected");
broadcast(nickname + " has joined the chat");
String message;
while((message = in.readLine()) !=null){
if (message.startsWith("/nick"))
{
// TODO: handle nickname
String[] messageSplit = message.split(" ", 2);
if(messageSplit.length == 2){
broadcast(nickname + " renamed themselves to " + messageSplit[1]);
System.out.println(nickname + " renamed themselves to " + messageSplit[1]);
nickname = messageSplit[1];
out.println("Successfully changed nickname to " + nickname);
}else{
out.println("No nickname provided");
}
}
else if(message.startsWith("/quit")){
broadcast(nickname + " has left the chat");
// shutdown();
}
else{
broadcast(nickname + ": " + message);
}
}
} catch(IOException e){
if(this.in != null && this.out != null){
shutdown();
}
}
}
}
public void sendMessage(String message){
out.println(message);
}
public void shutdown(){
try{
in.close();
out.close();
if(!client.isClosed()){
client.close();
}
}catch(IOException e){
// ignore
}
}
}
public static void main(String[] args) {
// TODO code application logic here
Server server =new Server();
server.run();
}
}
below is the client class in which client has been implemented. A great number of clients can connect to the server through cmd.
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package java_40;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class client implements Runnable{
private Socket client;
private BufferedReader in;
private PrintWriter out;
private boolean done;
#Override
public void run() {
try{
Socket client = new Socket("127.0.0.1",9999); // if you want to connect to someone elses server replace the ip with their ip as of now this our own ip
out = new PrintWriter(client.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
InputHandler inHandler = new InputHandler();
Thread t = new Thread(inHandler);
t.start();
String inMessage;
while((inMessage = in.readLine()) != null )
{
System.out.println(inMessage);
}
}catch(IOException e){
// shutdown();
}
}
private void shutdown(){
done =true;
try{
in.close();
out.close();
if(!client.isClosed()){
client.close();
}
}catch(IOException e){
// ignore
}
}
class InputHandler implements Runnable{
#Override
public void run() {
try{
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
while(!done){
String message = inReader.readLine();
if(message.equals("/quits")){
inReader.close();
shutdown();
}else{
out.println(message);
}
}
}catch(IOException e){
// shutdown();
}
}
}
public static void main(String[] args) {
client c = new client();
c.run();
}
}
I am testing some TCP code and it seems to work fine except for one problem. The read from the socket hangs in one of the methods when there is nothing more to read:
Here is the TCP code:
package com.comp424.service;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TCPService implements Runnable
{
protected int serverPort;
protected InetAddress bindAddress;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread = null;
protected ExecutorService threadPool = Executors.newFixedThreadPool(10);
public TCPService(String host,int port)
{
serverPort = port;
try
{
bindAddress = InetAddress.getByName(host);
}
catch (UnknownHostException e)
{
throw new RuntimeException("Failed to get bind address", e);
}
}
private void start()
{
try
{
serverSocket = new ServerSocket(serverPort, 10, bindAddress);
}
catch (IOException e)
{
throw new RuntimeException("Cannot open port " + serverPort, e);
}
}
public void run()
{
synchronized (this)
{
runningThread = Thread.currentThread();
}
start();
while (!isStopped())
{
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
if (isStopped())
{
System.out.println("Server Stopped.");
break;
}
throw new RuntimeException("Error accepting client connection", e);
}
threadPool.execute(new ClientHandler(clientSocket));
}
threadPool.shutdown();
System.out.println("Server Stopped.");
}
public synchronized void stop()
{
isStopped = true;
try
{
serverSocket.close();
}
catch (IOException e)
{
throw new RuntimeException("Error closing server", e);
}
}
private synchronized boolean isStopped()
{
return isStopped;
}
}
package com.comp424.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import com.comp424.impl.dao.DaoFactory;
import com.comp424.intf.dao.ICourseDao;
import com.comp424.intf.dao.IPersonDao;
import com.comp424.intf.dao.IRegisterCourseDao;
import com.comp424.model.Course;
import com.comp424.model.Person;
public class ClientHandler implements Runnable
{
private static IRegisterCourseDao registrationDao;
private static IPersonDao personDao;
private static ICourseDao courseDao;
protected Socket clientSocket = null;
public ClientHandler(Socket socket)
{
registrationDao = DaoFactory.getInstance().getCourseRegistrationDao();
personDao = DaoFactory.getInstance().getPersonDao();
courseDao = DaoFactory.getInstance().getCourseDao();
clientSocket = socket;
}
public void run()
{
try
{
String command = null;
OutputStream output = clientSocket.getOutputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
command = buffer.readLine();
while (command != null)
{
String separator = ":";
StringTokenizer tokenizer = new StringTokenizer(command, separator);
List<String> tokens = new ArrayList<>();
while (tokenizer.hasMoreElements())
{
tokens.add((String) tokenizer.nextElement());
}
int operation = Integer.parseInt(tokens.get(0));
switch (operation)
{
case 1:
try
{
Person person = personDao.findByID(Long.parseLong(tokens.get(1)));
Course course = courseDao.findByID(Long.parseLong(tokens.get(2)));
registrationDao.register(person, course);
output.write(("0\r\n").getBytes());
}
catch (Exception e)
{
e.printStackTrace();
output.write(("1\r\n").getBytes());
}
break;
case 2:
try
{
Person person = personDao.findByID(Long.parseLong(tokens.get(1)));
Course course = courseDao.findByID(Long.parseLong(tokens.get(2)));
registrationDao.register(person, course);
output.write(("0\r\n").getBytes());
}
catch (Exception e)
{
e.printStackTrace();
output.write(("1\r\n").getBytes());
}
break;
case 3:
try
{
Person person = personDao.findByID(Long.parseLong(tokens.get(1)));
List<Course> courses = registrationDao.findByPerson(person);
for (Course c : courses)
{
output.write((c.getName() + "\r\n").getBytes());
}
}
catch (Exception e)
{
e.printStackTrace();
output.write(("1\r\n").getBytes());
}
break;
}
command = buffer.readLine();
}
output.close();
}
catch (IOException e)
{
// report exception somewhere.
e.printStackTrace();
}
}
}
And here is the code where it just hangs in findRegisteredCourses() after reading two strings returned instead of exiting the while loop:
while (response != null)
{
result.add(response);
System.out.println("findRegisteredCourses():Response = " + response);
response = reader.readLine();
}
Full code for findRegisteredCourses():
#Override
public List<String> findRegisteredCourses(String personID) throws Exception
{
try (Socket server = new Socket("localhost", 7000))
{
List<String> result = new ArrayList<>();
DataOutputStream writer = new DataOutputStream(server.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));
String operation = "3:" + personID + "\r\n";
writer.writeBytes(operation);
writer.flush();
String response = reader.readLine();
while (response != null)
{
result.add(response);
System.out.println("findRegisteredCourses():Response = " + response);
response = reader.readLine();
}
server.close();
return result;
}
}
You're continuing to try to read from the server until it's closed the socket - whereas the server is waiting for another command from the client. Neither side is going to do anything, as they're waiting for the other.
Basically, you need to change your protocol, either to have some "here's the end of the response" indication (such as an empty line, if that's not a valid value in the response data), or to only have a single request/response per connection.
Your suggested "fix" of using the ready() method is very broken - it basically means you assume there's no more data as soon as there's a pause. Maybe the server is taking a while to find the next item. Maybe there's a delay on the network - or maybe it's finished. You can't tell, and basically you're violating the design of streaming protocols (such as TCP) by trying to infer information from the fact that there's no data available right now. Don't do that - fix your protocol.
Deleted my original answer because it was wrong as per #Jon Skeet's comments. I now just send a special end of data token and it works fine.
The class Server:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server{
private int port;
private Socket client;
private ServerSocket server;
public Server(int port) {
try {
this.port = port;
setServer(new ServerSocket(this.port));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.start();
}
public void start() {
ArrayList<ClientHandler> clients = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(20);
System.out.println("Server started...");
while (true) {
try {
setClient(null);
setClient(getServer().accept());
if (getClient() != null) {
ClientHandler handler = new ClientHandler(getClient());
System.out.println("Client connected...");
clients.add(handler);
executor.execute(handler);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server server = new Server(4567);
}
public Socket getClient() {
return client;
}
public void setClient(Socket client) {
this.client = client;
}
public ServerSocket getServer() {
return server;
}
public void setServer(ServerSocket server) {
this.server = server;
}
}
Now, my Question is, is there a Problem in the class, which causes the UnknownHostException? I already tried to debug, but the problem lies in the class Client
The Class Client:
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 java.util.Scanner;
public class Client{
private String kennung;
private Socket server;
private String host;
private int port;
public Client(String kennung, String host, int port){
setKennung(kennung);
setHost(host);
setPort(port);
try {
setServer(new Socket(this.host, this.port));
//Scanner reader = new Scanner(this.server.getInputStream());
PrintWriter writer = new PrintWriter(getServer().getOutputStream(), true);
Scanner sc = new Scanner(System.in);
writer.println("The Client");
/*while(true){
boolean next = reader.hasNext();
if (next) {
String line = reader.nextLine();
if(!line.equals(null)){
System.out.println("From another one: " + line);
}
}
writer.println(sc.next());
}*/
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if( server != null){
try {
server.close();
} catch (IOException e) {
//ignore -> Server getting closed
}
}
}
}
public String getKennung() {
return kennung;
}
public void setKennung(String kennung) {
this.kennung = kennung;
}
public Socket getServer() {
return server;
}
public void setServer(Socket server) {
this.server = server;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public static void main(String[] args) {
Client testClient = new Client("testClient", "127.0.0.1", 4567);
System.out.println("Client created");
}
}
And Last, but not least: The Class ClientHandler that implements Runnable and runs a Thread, where I read the input from the client and write it to the server.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
public class ClientHandler implements Runnable {
public ArrayBlockingQueue<String> messsages;
Socket client;
public ClientHandler(Socket client) {
this.messsages = new ArrayBlockingQueue<>(20);
this.client = client;
}
#Override
public void run() {
PrintWriter writer = null;
Scanner reader = null;
try {
reader = new Scanner(this.client.getInputStream());
writer = new PrintWriter(this.client.getOutputStream(), true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String line = "";
while (!line.equals(".bye")) {
//System.out.println("Got something? " + reader.hasNext());
line = reader.nextLine();
if (reader.hasNext()) {
if (!line.equals(null)) {
System.out.println("Vom Client: " + line);
}
}
//writer.println("Admin-Message"); // Zum Testen
}
}
}
Thanks to everybody, who helps me with this problem.
I'm trying to play around with a simple client-server program, eventually aiming to make it a two-way communication. For some reason when I just instantiate the client class to make it connect to the server (without sending any data), it doesn't work, and throws Unable to establish loopback connection exception. When I put a while loop of reading through stdin, it works then. I need to establish a connection first, and then once in a while send a message to the server. How can I fix it?
Client code:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
public class ClientCore {
SelectionKey selkey;
Selector sckt_manager ;
SocketChannel sc;
public ClientCore() {
try {
sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(8888));
// should not proceed until connect is finished
while (!sc.finishConnect()) {
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (sc != null) {
try {
sc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
void send(String message) {
try {
if (!message.equalsIgnoreCase("end")) {
System.out.println("Sending a request to the server ...");
ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
sc.write(buffer);
}
} catch (IOException e) {
}
}
public static void main(String[] args) throws Exception {
ClientCore cl = new ClientCore();
cl.send("hello");
}
}
Server code:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.channels.spi.SelectorProvider;
public class ServerCore extends Thread {
SelectionKey selkey = null;
Selector sckt_manager = null;
public void run() {
try {
coreServer();
} catch (Exception ej) {
ej.printStackTrace();
}
}
private void coreServer() {
try {
ServerSocketChannel ssc = ServerSocketChannel.open();
try {
ssc.socket().bind(new InetSocketAddress(8888));
while (true) {
sckt_manager = SelectorProvider.provider().openSelector();
ssc.configureBlocking(false);
SocketChannel sc = ssc.accept();
register_server(ssc, SelectionKey.OP_ACCEPT);
if (sc == null) {
} else {
System.out
.println("Received an incoming connection from "
+ sc.socket().getRemoteSocketAddress());
printRequest(sc);
System.err.println("testing 1");
String HELLO_REPLY = "Sample Display";
ByteBuffer buffer = ByteBuffer.wrap(HELLO_REPLY .getBytes());
System.err.println("testing 2");
sc.write(buffer);
System.err.println("testing 3");
sc.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ssc != null) {
try {
ssc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (Exception E) {
System.out.println("Ex in servCORE " + E);
}
}
private static void printRequest(SocketChannel sc) throws IOException {
ReadableByteChannel rbc = Channels.newChannel(sc.socket()
.getInputStream());
WritableByteChannel wbc = Channels.newChannel(System.out);
ByteBuffer b = ByteBuffer.allocate(1024); // read 1024 bytes
while (rbc.read(b) != -1) {
b.flip();
while (b.hasRemaining()) {
wbc.write(b);
System.out.println();
}
b.clear();
}
}
public void register_server(ServerSocketChannel ssc, int selectionkey_ops)
throws Exception {
ssc.register(sckt_manager, selectionkey_ops);
}
public static void main(String[] args) {
ServerCore st = new ServerCore();
st.coreServer();
}
}
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.