ObjectOutputStream - client/server communication - java

I am new to java client server communications and I'm confronted with sending an object from client side to server side. Somehow my programm stucks while trying to transfer an object. The likely reason might be the ObjectOutputStream implementation.
Database login button
class Handler implements ActionListener {
Client client = new Client();
List<String> parameterList = new ArrayList<String>();
ClientParameter parameter;
public void actionPerformed(ActionEvent event) {
if(event.getSource()==buttonConnect) {
parameterList.add(username);
parameterList.add(password);
parameter = new ClientParameter(parameterList);
client.connectToServer(parameter);
}
Object ClientParameter
public class ClientParameter {
List<String> parameterList;
public ClientParameter(List<String> parameterList) {
this.parameterList = parameterList;
}
public List<String> getParameterList() {
return parameterList;
}
public void setParameterList(List<String> parameterList) {
this.parameterList = parameterList;
}
}
Class client
public void connectToServer(ClientParameter parameter) {
// Verbindung mit dem Server herstellen
Socket server = null;
try {
server = new Socket("localhost", 3141);
// programm hangs while reading this 2 lines..
ObjectInputStream objectIn = new ObjectInputStream(server.getInputStream());
ObjectOutputStream objectOut = new ObjectOutputStream(server.getOutputStream());
objectOut.writeObject(parameter);
} catch(UnknownHostException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} finally {
if(server!=null) {
try {
server.close();
} catch(IOException e) {
System.out.println(e);
}
}
}
}
And the server class
public class Server {
private static void handleConnection(Socket client) throws IOException {
ObjectInputStream objectIn = new ObjectInputStream(client.getInputStream());
ObjectOutputStream objectOut = new ObjectOutputStream(client.getOutputStream());
ClientParameter parameter;
try {
parameter = (ClientParameter) objectIn.readObject();
System.out.println(parameter);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(3141);
while(true) {
Socket client = null;
try {
client = server.accept();
handleConnection(client);
}
catch(IOException e) {
e.printStackTrace();
}
finally {
if(client!=null) {
try {
client.close();
}
catch(IOException e) {
System.out.println(e);
}
}
}
}
}
}
Thank you!

The server starts by reading what the client sends. And the client also starts by reading what the server sends. So it's a deadlock.
Indeed, as documented, the constructor of ObjectInputStream blocks until it has received the serialization stream header:
A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
Remove the following line, since you don't do anything with the ObjectInputStream anyway:
ObjectInputStream objectIn = new ObjectInputStream(server.getInputStream());

Related

StreamCorruptedException: invalid type code: 64

I'm trying to send Message object from Server module to Client module. Unfortunately it throw java.io.StreamCorruptedException: invalid type code: 64 error. Does anyone know what is the problem with code below?
Client class from Server module
private boolean needToRun;
public final Socket socket;
private OutputStream outputStream;
private InputStream inputStream;
private ObjectOutputStream objOut;
private ObjectInputStream objIn;
public Client(Socket socket) {
this.needToRun = true;
this.socket = socket;
try {
this.outputStream = socket.getOutputStream();
this.inputStream = socket.getInputStream();
this.objOut = new ObjectOutputStream(outputStream);
this.objIn = new ObjectInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
run();
}
public void send(Message msg) {
try {
objOut.writeObject(msg);
objOut.flush();
objOut.reset();
} catch (Exception ex){
ex.printStackTrace();
}
}
public void close() {
needToRun = false;
}
public void run() {
new Thread(() -> {
while(needToRun) {
try {
int amount = inputStream.available();
if (amount != 0) {
Message msg = (Message) objIn.readObject();
receivedContent(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void receivedContent(Message msg) {
for (Client connection : Server.clients) {
connection.send(msg);
}
}
the Client class from Client module looks the same but receivedContent looks like this:
public void receivedContent(Message msg) {
String errorName = msg.content().trim();
MainPane.addLabel(errorName);
}
and last one Server class, which accepts socket connections:
while (true) {
System.out.println("running");
try {
System.out.println("Waiting for client...");
Socket socket = serverSocket.accept();
clients.add(new Client(socket));
} catch (Exception e) {
if (!serverSocket.isClosed()) {
stopServer();
}
break;
}
}

Muti - threaded Web Server in Java

I'm trying to build a server with Java.
My question is: how to do if I have multiple users at the same time? The answer is: multi threading. But I don't know how to do.
For example, if there is two client connected at the same time, and a server (who does 2*number) : if the client1 say "50" to the server and the client 2 "10", the server is supposed to return "100" to the first client and "20" to the second. But i'm not sure my code works.
Server side:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
socket = new ServerSocket(4444);
Thread t = new Thread(new Accept(socket));
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private ServerSocket socketserver;
private Socket socket;
private int nbrclient = 1;
public Accept(ServerSocket s){
socketserver = s;
}
public void run() {
try {
socket = socketserver.accept();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
out = new PrintWriter(socket.getOutputStream());
out.println("Pong");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client side:
public class Client {
public static void main(String[] zero) {
Socket socket;
BufferedReader in;
PrintWriter out;
try {
socket = new Socket(InetAddress.getLocalHost(),4444);
out = new PrintWriter(socket.getOutputStream());
out.println("Ping");
out.flush();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
socket.close();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
If you have any ideas (how to do multi-threading and how to verify if my code works, like run two Clients.java and check if the multi-threading works)
The Server sides needs a while loop:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
while(true){
socket = new ServerSocket(4444);
Socket socketInstance = socket.accept();
Thread t = new Thread(new Accept(socketInstance));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private Socket socket;
private int nbrclient = 1;
public Accept(Socket s){
socket = s;
}
public void run() {
try {
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);//this message should be your number
Double number = Double.parseString(message);
out = new PrintWriter(socket.getOutputStream());
//out.println("Pong");
out.println(2*number +"");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client side looks ok. Just replace out.println("Ping"); with out.println("50"); or whatever you want.
You first start the server and then you can start multiple client applications. If you have any errors you can then post them here and have a look on an exact scenario.

Multithreaded proxy application is not working

I'm trying to create a proxy application, but I'm facing problems in server socket. The Server Socket is not accepting the connection and returning a socket. Hence, I cannot test the proxy application. What is wrong?
The problem line is indicated in WebServe.java:
public class WebServe implements Runnable {
Socket soc;
OutputStream os;
BufferedReader is;
String resource;
WebServe(Socket s) throws IOException {
soc = s;
os = soc.getOutputStream();
is = new BufferedReader(new InputStreamReader(soc.getInputStream()));
}
public void run() {
System.err.println("Running");
getRequest();
returnResponse();
close();
}
public static void main(String args[]) {
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket(8080);
for (;;) {
s.setSoTimeout(10000);
WebServe w = new WebServe(s.accept()); // Problem is here
Thread thr = new Thread(w);
thr.start();
w.getRequest();
w.returnResponse();
w.close();
}
} catch (IOException i) {
System.err.println("IOException in Server");
}
}
void getRequest() {
System.out.println("Getting Request");
try {
String message;
while ((message = is.readLine()) != null) {
if (message.equals("")) {
break;
}
System.err.println(message);
StringTokenizer t = new StringTokenizer(message);
String token = t.nextToken();
if (token.equals("GET")) {
resource = t.nextToken();
}
}
} catch (IOException e) {
System.err.println("Error receiving Web request");
}
}
void returnResponse() {
int c;
try {
FileInputStream f = new FileInputStream("." + resource);
while ((c = f.read()) != -1) {
os.write(c);
}
f.close();
} catch (IOException e) {
System.err.println("IOException is reading in web");
}
}
public void close() {
try {
is.close();
os.close();
soc.close();
} catch (IOException e) {
System.err.println("IOException in closing connection");
}
}
}
public static void main(String args[]){
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket (8080);
for (;;){
s.setSoTimeout(10000);
Move that ahead of the loop. You don't need to keep setting it. You don't really need it at all actually.
WebServe w = new WebServe (s.accept()); //Problem is here
The problem is here only because you set a socket timeout you don't actually need.
Thread thr = new Thread (w);
thr.start();
So far so good.
w.getRequest();
w.returnResponse();
w.close();
Remove. The next problem is here. The run() method of WebServ already does this.
As to the rest, you aren't writing an HTTP header in the response.

java.net.BindException: Address already in use: JVM_Bind Multi Client Server

I have a Server project and a Client project. While the Server is running the first connection from client works fine. At the seccond connection the Server fires the "java.net.BindException: Address already in use: JVM_Bind " error. Is there a way to add more connections on the same port?
Server:
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket pipe = null;
while(true){
ServerSocket s = new ServerSocket(2345);
pipe = s.accept();
Connection c = new Connection(pipe);
c.start();
}
}
}
public class Connection extends Thread{
private Socket socket = null;
Mensch jim = null;
ObjectInputStream input = null;
ObjectOutputStream output = null;
ServerSocket s = null;
public Connection(Socket s){
socket = s;
}
public void run(){
try {
input = new ObjectInputStream(socket.getInputStream());
output = new ObjectOutputStream(socket.getOutputStream());
jim = (Mensch) input.readObject();
jim.setAge(33);
output.writeObject(jim);
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
And the Client:
public class Main {
public static void main(String[] args) {
Mensch jim = new Mensch(19, "Jim");
System.out.println(jim.getAge());
try {
Socket s = new Socket("127.0.0.1", 2345);
ObjectOutputStream clientOutputStream = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream clientInputStream = new ObjectInputStream(s.getInputStream());
clientOutputStream.writeObject(jim);
jim = (Mensch) clientInputStream.readObject();
System.out.println(jim.getAge());
clientOutputStream.close();
clientInputStream.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is the problem:
while(true) {
ServerSocket s = new ServerSocket(2345);
pipe = s.accept();
...
}
You're trying to bind to the same port repeatedly. All you need to do is create a single ServerSocket and call accept on it multiple times. (I'd also move the pipe variable declaration inside the loop...)
ServerSocket s = new ServerSocket(2345);
while(true) {
Socket pipe = s.accept();
...
}

Sending multiple variables through a socket?

I recently started learning networking with sockets in java. So i've created a multiplayer game that is playable on the same computer but i wanted to make it network-multiplayer, then i learned about sockets, now, i want to send the variables of the position of the player in the game to a server which then can place that player in that position in the other game instance running on a different machine. And the thing is, i just fail at it and all the data doesnt get received or read. I also want the position to get sent and received constantly which is also a problem for me...
I tried using ObjectOutputStream and ObjectInputStream to send a int array with the variables but that also failed, so could you please show me how to do this, because i have no idea and i cant seem to find an answer online.
Thx
As the easiest solution, use the Object Streams to send an object created by you where you store these coordinates, but this class must implement Serializable interface. For example for 2d coordinates:
class Coords implements Serializable {
int x, y;
public Coords(int x, int y) {
this.x = x;
this.y = y;
}
}
...
// To write:
// oos = ObjectOutputStream of the socket
Coords tmp = new Coords(x, y);
oos.writeObject(tmp);
oos.flush();
...
//To read:
//ois = ObjectInputStream of the socket
Coords tmp = (Coords)ois.readObject();
http://java.sun.com/developer/technicalArticles/ALT/sockets/ can also aid you.
try something like this:
import java.io.*;
import java.net.*;
class Server extends Thread {
Server() throws IOException {
serverSocket = new ServerSocket(0);
}
public void run() {
while (true) {
try {
Socket client = serverSocket.accept();
Connect c = new Connect(client);
c.start();
} catch (Exception e) {}
}
}
final ServerSocket serverSocket;
}
class Data implements Serializable {
int[] data = { 1, 2, 3 };
}
class Connect extends Thread {
public Connect(Socket clientSocket) {
client = clientSocket;
try {
ois = new ObjectInputStream(client.getInputStream());
oos = new ObjectOutputStream(client.getOutputStream());
} catch (Exception e1) {
try {
client.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return;
}
}
public void run() {
try {
oos.writeObject(new Data());
oos.flush();
ois.close();
oos.close();
client.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("done");
}
final Socket client;
ObjectInputStream ois;
ObjectOutputStream oos;
}
class Client {
Client(int port) {
this.port = port;
}
void connectAndRead() {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket socket = null;
Data data = null;
try {
socket = new Socket("127.0.0.1", port);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
data = (Data) ois.readObject();
oos.close();
ois.close();
for (int d : data.data)
System.out.println(d);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
final int port;
}
public class Main {
public static void main(String[] arguments) throws IOException, InterruptedException {
Server server = new Server();
server.start();
Client client = new Client(server.serverSocket.getLocalPort());
client.connectAndRead();
}
}

Categories