UnknownHostException in Java Client/Server-Programm - java

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.

Related

Java Socket programming with more than one client

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.

Need help on a simple server/multiple client chat application

this is the scenario .. i have 2 clients connected to a server.. i want them to be able to chat with eachother. After a couple of messages i get this error.
Exception in thread "Thread-0" java.lang.ClassCastException:
java.io.ObjectStreamClass cannot be cast to message.Mesaj
at server.ServerThread.readAndWrite(ServerThread.java:43)
at server.ServerThread.run(ServerThread.java:61)
java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at server.ServerThread.readAndWrite(ServerThread.java:43)
at server.ServerThread.run(ServerThread.java:61)
This is the client:
package client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import message.Mesaj;
public class Client {
public static int port=4321;
public static Socket socket;
public static ObjectOutputStream oo;
public static ObjectInputStream oi;
public static Scanner sc;
public Client() throws IOException{
socket = new Socket ("localhost",4321);
oi = new ObjectInputStream(socket.getInputStream());
oo = new ObjectOutputStream(socket.getOutputStream());
}
public static void listen() throws ClassNotFoundException, IOException{
while(true){
Mesaj m = (Mesaj) oi.readObject();
if(m!=null){
System.out.println("mesajul este: " + m.getMesaj());
}
}
}
public static void write() throws IOException{
sc= new Scanner(System.in);
while(true){
String trimite= sc.nextLine();
Mesaj m = new Mesaj();
m.setMesaj(trimite);
oo.writeObject(m);
oo.flush();
}
}
public static Thread t = new Thread(){
public void run(){
try {
listen();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public static Thread t2 = new Thread(){
public void run(){
try {
write();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public static void main(String[] args) throws IOException{
new Client();
t.start();
t2.start();
}
This is the Server:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public int port;
public static Socket socket;
public static ServerSocket serverSocket;
public Server() throws IOException{
this.port=4321;
serverSocket = new ServerSocket(port);
}
public static void main (String [] args){
try {
new Server();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Server functionabil..asteptam conexiune client");
while(true){
try {
socket= serverSocket.accept();
ServerThread st= new ServerThread(socket);
st.start();
System.out.println("Conexiune realizata -client conectat");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
..and this is the Server Thread:
package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import message.Mesaj;
public class ServerThread extends Thread {
boolean running;
public static ObjectOutputStream oo;
public static ObjectInputStream oi;
public static Mesaj m;
public static Socket socket;
public ServerThread(Socket socket) throws ClassNotFoundException{
try {
running=true;
this.socket=socket;
oo = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void readAndWrite() throws ClassNotFoundException, IOException{
oi = new ObjectInputStream(socket.getInputStream());
while(true){
m= (Mesaj) oi.readObject();
if(m!=null){
oo.writeObject(m);
oo.flush();
System.out.println(m.getMesaj());
}
}
}
public void run(){
System.out.println("Server Thread contectat");
try {
readAndWrite();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
EDIT:
This is the message class:
package message;
import java.io.Serializable;
public class Mesaj implements Serializable {
private String mesaj;
public String getMesaj() {
return mesaj;
}
public void setMesaj(String mesaj) {
this.mesaj = mesaj;
}
}
You having concurrency issues.
Both serverthreads access the same static outputstream, meaning that there is a change for corruption as Object streams aren't designed for this.
In ServerThread, remove static from all the variables and the method "readAndWrite".
public ObjectOutputStream oo;
public ObjectInputStream oi;
public Mesaj m;
public Socket socket;
...
public void readAndWrite() throws ClassNotFoundException, IOException{
If you want to access the output streams from multiple threads, you should synchronize on them.

My simple Java NIO client server non-blocking connection does not work

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();
}
}

send a message to specific client threads

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.

could not disconnect socket

Here is my tcpClient class:
import java.io.*;
import java.net.*;
public class tcpClient
{
private String _ip;
private int _port;
private Socket _clientSocket;
public tcpClient(String IP, int Port)
{
_ip = IP;
_port = Port;
}
public boolean createSocket()
{
boolean retSt = false;
try
{
_clientSocket = new Socket(this._ip, this._port);
retSt = true;
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return retSt;
}
public boolean disposeSocket()
{
boolean retSt = false;
try
{
_clientSocket.shutdownInput();
_clientSocket.shutdownOutput();
_clientSocket.close();
retSt = true;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return retSt;
}
public boolean isConnected()
{
return _clientSocket.isConnected();
}
}
Here is my main method:
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
public class cos
{
public static void main(String[] args)
{
tcpClient client = new tcpClient("192.168.10.39", 1234);
client.createSocket();
System.out.println(client.isConnected());
client.disposeSocket();
System.out.println(client.isConnected());
client.createSocket();
System.out.println(client.isConnected());
client.disposeSocket();
System.out.println(client.isConnected());
}
}
Here is my console output:
true
true
true
true
Why couldn't i disconnect from server?
from java doc:
Note: Closing a socket doesn't clear its connection state, which means
this method will return true for a closed socket (see isClosed()) if
it was successfuly connected prior to being closed.

Categories

Resources