Java networking, cant figureout what's wrong with multithread server - java

my name is Jędrzej and I am new here. I was trying to write a simple chat in java. I am trying to make multithread server so multiple clients can connect to this server. My client works fine, but if I run two clients, they dont see each others responses. Code bellow:`
package serverthread;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerWIthThreads {
public static void main(String[] args){
try{
ServerSocket serverSocket = new ServerSocket(1234);
while(true){
Socket socket = serverSocket.accept();
Runnable r = new ThreadForServer(socket);
Thread t = new Thread(r);
t.start();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
package serverthread;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ThreadForServer implements Runnable{
private Socket socket;
private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
public ThreadForServer(Socket i){
socket = i;
}
#Override
public void run(){
try{
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.flush();
while(true){
String message = (String) inputStream.readObject();
outputStream.writeObject(message);
outputStream.flush();
}
}catch(IOException e){
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
`

The way you've implemented this, you're reading a message from one client and then writing it back to the same client.
You'll need to revise your program so that you can write the message to the Socket of the other connected client.

Related

How do I send objects back and forth continuously across sockets in Java?

What I am trying to do here is create an application that will be a basic game, and first I have to get the networking functional. I'm struggling to send objects back and forth between server and client. The design I am trying to achieve is 2 processes with 2 threads each, the main thread and then a listener thread. I want the listener thread to listen for incoming objects, as this will be used for an event bus. Currently to get it working I'm using just a simple message class which holds a single string field called text. The issue I'm having is that the client listener thread doesn't seem to start, and the objects never get sent either way. Really struggling learning network programming here, any help is much appreciated.
Server side
package Server;
import java.net.*;
import java.util.List;
import Utilities.Message;
import java.io.*;
public class BattleshipServer
{
public static void executeThreadedServer(int port) throws Exception
{
ServerSocket server = new ServerSocket(port);
System.out.println("Awaiting connection");
Socket socket = server.accept();
System.out.println("Connection established");
BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
//Start the listener thread
ServerListener sListener = new ServerListener(kb, out, in);
sListener.run();
Message msg = new Message("temp");
while(!msg.getText().equalsIgnoreCase("exit"))
{
msg = new Message(kb.readLine());
out.writeObject(msg);
out.flush();
}
}
}
------------------------------------------------------------------------------------------------------------
package Server;
import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import Utilities.Message;
public class ServerListener implements Runnable
{
private BufferedReader keyBoard;
private ObjectOutputStream out;
private ObjectInputStream in;
public ServerListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
{
this.keyBoard = keyboard;
this.out = out;
this.in = in;
}
#Override
public void run()
{
System.out.println("Server listener started");
try {
while(true)
{
Message msg;
while((msg = (Message)this.in.readObject()) != null)
{
System.out.println(msg.getText());
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Client Side
package Client;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import Utilities.Message;
import java.io.*;
public class BattleshipClient
{
public static void executeThreadedClient(String address, int port) throws Exception
{
Socket socket = new Socket(address, port);
BufferedReader kb = new BufferedReader(new InputStreamReader(System.in));
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ClientListener cListener = new ClientListener(kb,out,in);
cListener.run();
Message msg = new Message("temp");
while(!msg.getText().equalsIgnoreCase("exit"))
{
msg = new Message(kb.readLine());
out.writeObject(msg);
out.flush();
}
socket.close();
}
}
------------------------------------------------------------------------------------------------------------
package Client;
import java.io.BufferedReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import Utilities.Message;
public class ClientListener implements Runnable
{
private BufferedReader keyBoard;
private ObjectOutputStream out;
private ObjectInputStream in;
public ClientListener(BufferedReader keyboard, ObjectOutputStream out, ObjectInputStream in)
{
this.keyBoard = keyboard;
this.out = out;
this.in = in;
}
#Override
public void run()
{
System.out.println("Client listener started");
try
{
while(true)
{
Message msg = (Message)in.readObject();
System.out.println(msg.getText());
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Although your ClientListener and ServerListeners are implementing Runnable, they are not run in a separate thread. In your implementation, it is just another function call and therefore the code after the listener.run() never gets called.
So instead of doing:
ClientListener cListener = new ClientListener(kb,out,in);
cListener.run();
You need to do something like:
Thread clientThread = new Thread(new ClientListener(kb,out,in));
clientThread.start();
And on the server side you need to do something similar.

Java Beginner - Issue with Socket Connection refused

I am complete beginner and i have assignment to send something to server and get it back while using threads too.
My problem is that no matter which port I use, I get connection refused.
I think it might something to do with threads, but I am unsure what to do with them as it seems both start properly and client is the one throwing exception. I read somewhere that server should have some time to start connection so I put sleep but same thing again.
Main:
package advancedjavaassignment1;
public class MAIN {
public static void main(String[] args) {
SERVER.mainServer();
CLIENT.mainClient();
}
}
SERVER:
package advancedjavaassignment1;
import java.net.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class SERVER {
static void mainServer() {
serverTHREAD serverThread = new serverTHREAD();
serverThread.start();
try (
ServerSocket calcServer = new ServerSocket(10001); //Server created on port 2390
Socket inSocket = calcServer.accept(); //Server is listening
DataInputStream FromClient = new DataInputStream(inSocket.getInputStream());
DataOutputStream ToClient = new DataOutputStream(inSocket.getOutputStream());) {
int a = FromClient.readInt();
ToClient.writeInt(a);
}
catch (IOException e) {
System.out.println(e.getMessage()+ "Server");
}
}
}
}
CLIENT:
package advancedjavaassignment1;
import java.net.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class CLIENT {
static void mainClient() {
serverTHREAD clientThread = new serverTHREAD();
clientThread.start();
try {Thread.sleep(2000); System.out.println("break");} catch (InterruptedException ex) { }
try (Socket ClientSocket = new Socket("localhost",80);
DataInputStream FromServer = new DataInputStream(ClientSocket.getInputStream());
DataOutputStream ToServer = new DataOutputStream(ClientSocket.getOutputStream());) {
ToServer.writeInt(10);
int sum = FromServer.readInt();
System.out.println(sum);
ClientSocket.close();
}
catch(IOException exception)
{
System.out.println(exception.getMessage() + " - Client");
}
}
}
Looks like your server runs on port 10001 (although you wrote 2390 in the comment) and the client tries to connect to port 80. The client finds no server listening on that port, hence the connection refused error.
My apology, I forgot to change it, as I was experimenting with everything, this does not work even when ports are same.
I solved this by implementing Runnable. Worked immediately.

Java sockets application with two listeners hanging

I'm running a client and server on my local machine and trying to send text messages between the two. Both sides are able to read and write. I'm using ObjectInputStream and ObjectOutputStream because I need to serialize objects. Github repo
My issue is when I try to send messages from both sides, they don't get through to the other side and the listeners hang.
Host.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Host {
private ServerSocket serverSocket;
private Socket clientSocket;
private ObjectOutputStream out;
private ObjectInputStream in;
private int portNumber = Settings.PORT;
public Host() {
acceptConnection();
CommandListener commandListener = new CommandListener(in);
}
private void acceptConnection() {
try {
serverSocket = new ServerSocket(portNumber);
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
public ObjectOutputStream getOut() {
return out;
}
public ObjectInputStream getIn() {
return in;
}
}
Client.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
private int portNumber = Settings.PORT;
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket clientSocket;
public Client(String ip) {
connectToHost(ip);
CommandListener commandListener = new CommandListener(in);
}
public ObjectOutputStream getOut() {
return out;
}
public ObjectInputStream getIn() {
return in;
}
private void connectToHost(String ip) {
try {
clientSocket = new Socket(ip, portNumber);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + ip);
e.printStackTrace();
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " + ip);
e.printStackTrace();
}
}
}
The CommandListener.java class is a thread which is started independently by both the client and the server.
import java.io.IOException;
import java.io.ObjectInputStream;
public class CommandListener implements Runnable{
private ObjectInputStream in;
public CommandListener(ObjectInputStream in) {
this.in = in;
run();
}
public void run() {
String inboundCmd;
try {
System.out.println("listener running, waiting for inbound command");
inboundCmd = (String) in.readObject();
System.out.println("listener read inbound command" + inboundCmd);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Both hang after printing out listener running, waiting for inbound command.
Here's how I start the client and the server:
RunHost.java
import java.io.IOException;
import java.io.ObjectOutputStream;
public class RunHost {
public static void main(String[] args) throws IOException {
Host host = new Host();
ObjectOutputStream out = host.getOut();
out.writeObject("host sending");
out.flush();
}
}
RunClient.java
import java.io.IOException;
import java.io.ObjectOutputStream;
public class RunClient {
public static void main(String[] args) throws IOException {
Client client = new Client("localhost");
ObjectOutputStream out = client.getOut();
out.writeObject("client sending");
out.flush();
}
}
Any idea how to fix this?
The reason why it seems like both the host and the client are "hanging" is simply because nobody managed to write anything before listening to the other party.
You should be running RunHost.java before RunClient.java. Starting from there, you can trace the program:
Construct a new Host (i.e. RunHost.java is ran)
Blocks and wait for a client socket to connect
Construct a new Client (i.e. RunClient.java is ran)
Both ServerSocket's and ClientSocket's input and output streams are initialised
Both ServerSocket and ClientSocket start constructing CommandListener
Both ServerSocket and ClientSocket start listening for an input
See the problem yet? The main issue is because you call the method run() within the CommandListener constructor, so both Server and Client side start to block on listening without anyone having sent anything.
A quick fix would be to take out the run() call from the CommandListener constructor function, and then call it separately when you are ready for it.
For example:
Change the constructor in CommandListener.java to:
public CommandListener(ObjectInputStream in) {
this.in = in;
}
Add a way to get the CommandListener for the client in Client.java (note that this means you should store the CommandListener by doing cl = new CommandListener(in); in the Client constructor):
public CommandListener getCL() {
return cl;
}
Change RunClient.java to something like:
public static void main(String[] args) throws IOException {
Client client = new Client("localhost");
ObjectOutputStream out = client.getOut();
out.writeObject("client sending");
out.flush();
CommandListener cl = client.getCL();
cl.run();
}
And lastly, call CommandListener's run() method in Host's constructor:
public Host() {
acceptConnection();
CommandListener commandListener = new CommandListener(in);
commandListener.run();
}
And it should work as per expected.
But to be honest, given the mess that CommandListener is causing, you may want to reconsider having that class in the first place. I mean, over here it doesn't seem to be necessary, so...
P/S Feel free to let me know if anything is unclear/ it still does not work

Java server / client sending array, Check in check out

Im having a little problem i have managed to send info from client to server etc... but i want to be able to do it though telnet also (Open it up and say go telnet 127.0.0.1 4444, and then put in like 1 2 3 and then it comes up in the server just like it would if sending via the client. At the moment im getting this error:
java.io.StreamCorruptedException: invalid stream header: 310D0A32
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at ConnectionHandler.run(server1.java:73)
at java.lang.Thread.run(Unknown Source)
Let me know if i'm doing anything wrong please:
My main goal for this is to have it so i can enter say Username, ID and Name and then be able to recall them with a time, Like a very simple check in check out system. Would really love some help <3 :)
Client:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class client1 {
public static void main(String[] args) {
try {
// Create a connection to the server socket on the server application
Socket socket = new Socket("localhost", 7777);
// Send a message to the client application
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
//oos.writeObject("A B C");
String data[]=new String[3];
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter details for the array");
for(int x=0;x<3;x++){
System.out.print("Enter word number"+(x+1)+":");
data[x]=br.readLine();
}
oos.writeObject(data);
System.out.println("Details sent to server...");
oos.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ClassNotFoundException;
import java.lang.Runnable;
import java.lang.Thread;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class server1
{
private ServerSocket server;
private int port = 4444;
public server1()
{
try
{
server = new ServerSocket(port);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
server1 example = new server1();
example.handleConnection();
}
public void handleConnection()
{
System.out.println("Waiting for client message got...");
// The server do a loop here to accept all connection initiated by the
// client application.
while (true)
{
try
{
Socket socket = server.accept();
new ConnectionHandler(socket);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable
{
private Socket socket;
public ConnectionHandler(Socket socket)
{
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run()
{
try
{
// Read a message sent by client application
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message[] = (String[]) ois.readObject();
//System.out.println("Message Received from client: " + message);
//b(message);
printArray(message);
ois.close();
socket.close();
System.out.println("Waiting for client message is...");
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
private void b(String message) {
List<String> list = new ArrayList<String>();
String[] arr = list.toArray(new String[0]);
System.out.println("Array is " + Arrays.toString(arr));
}
private void printArray(String[] arr){
for(String s:arr){
System.out.println(s);
}
}

Java socket reading and writeing hex code

I'm working on a project and i want to comunicate with a device. I made a socket connection with the device, the connection works but the device is sending me the message: 0xd7d0 and i have to write that message back. It's a keep alive message. I'm haveing trouble reading and sending back that message.
here's the code i've writen so far:
package Server;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
public static ServerSocket serverSocket;
public static void main (String [] args) {
try {
serverSocket = new ServerSocket(1234);
while (true) {
ServerThread serverThread = new ServerThread(serverSocket.accept());
serverThread.start();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
package Server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerThread extends Thread {
public Socket socket;
public BufferedReader in;
public PrintWriter out;
public ByteBuffer buf;
int count;
public ServerThread (Socket socket) {
try {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void run() {
while (true) {
try {
count = in.read();
buf = ByteBuffer.allocate(100);
buf.put((byte) count);
buf.flip();
out.println(buf);
String line = in.readLine();
System.out.println(line);
} catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Can anyone tell me what i am doing wrong?
This
while (true) {
ServerThread serverThread = new ServerThread(serverSocket.accept());
serverThread.start();
}
doesn't look right. You're looping and creating a new thread repeatedly (which will consume resources and create an enormous number of threads). You should simply create that thread once. If your program is doing nothing else then a new thread may be superfluous.
Your mistake is that you mix different styles of network data exchange. First, what format are messages in? Are they characters in some encoding, or some binary data? In the first case, you should not use Buffer to read message in, but read and write using in and out character streams you created already. In the second case, you have 2 options: read and write with socket and byte streams, or with channels from java.nio.channels and Buffers. To write back a message in a buffer, you can use
buf.flip();
buffer.position(buffer.limit());

Categories

Resources