best ways for optimizing socket programming in java? [closed] - java

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
i try to program a part of a university research project about multi client - server socket programming.my code works as well as so that i give valide result but the problem is that evalutor of our group said that my code have not a good speed on connection for data transfer.i will be thankfull if you found the problem(s) in my code that cause this issue.
server part:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import j
ava.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
/**
*
*/
/**
* #author Sina
*
*/
public class BoxServer {
ServerSocket serversocket;
static ThreadHandler t[]=new ThreadHandler[100];
static int size=0;
static ArrayList<Message> messagebox=new ArrayList<Message>();
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(79);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true)
{
try{
//InetAddress inetadress=InetAddress.getLocalHost();
//System.out.println(inetadress);
//System.out.println(inetadress.getHostName());
//System.out.println(inetadress.getHostAddress());
Socket socket=serverSocket.accept();
if(socket==null)
{
System.out.println("null");
}
t[size]=new ThreadHandler(socket,"username");
size++;
t[size-1].start();
}
catch(UnknownHostException e){
System.out.println("salam s");
System.out.println(e.getMessage());
}
catch (IOException e) {
System.out.println("bye s");
System.out.println(e.getMessage());
}
}
}
}
class ThreadHandler extends Thread{
private String socname;
Socket mySocket;
ObjectInputStream inp;
ObjectOutputStream outp;
public ThreadHandler(Socket s,String socketName)
{
this.mySocket=s;
this.socname=socketName;
}
public void run()
{
try {
inp=new ObjectInputStream(mySocket.getInputStream());
outp=new ObjectOutputStream(mySocket.getOutputStream());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true)
{
System.out.println("thread run");
System.out.println(mySocket.getLocalPort());
System.out.println(mySocket.getLocalAddress());
try {
// System.out.println("my socket:"+mySocket.getOutputStream());
System.out.println(mySocket.isConnected());
System.out.println(inp.available());
System.out.println("inp = "+inp);
System.out.println("reeead "+ inp.readObject());
Message mess=(Message)inp.readObject();
System.out.println("dsd");
System.out.println("mess: "+mess);
BoxServer.messagebox.add(mess);
if(mess.getReceiver().equals("system-use:code=1"))
{
System.out.println(mess.getSender()+" wants to see his/her Inbox");
}
//mySocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("bug dar thread");
e.printStackTrace();
}
}
}
}
client part
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import javax.swing.Timer;
public class Main {
/**
* #param args
*/
static Socket socket=new Socket();
public static void main(String[] args) {
System.out.println("newuser(n) or login(l)");
Scanner scanner=new Scanner(System.in);
String typeOfOperation=scanner.nextLine();
if(typeOfOperation.equals("n"))
{
}
else
if(typeOfOperation.equals("l"))
{
try {
socket = new Socket("127.0.0.1",79);
final ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in=new ObjectInputStream(socket.getInputStream());
while(true)
{
Thread timer=new Thread()
{
public void run()
{
while(true)
{
Message temp=new Message();
temp.setReceiver("system-use:code=1");
temp.setSender("username");
try {
out.writeObject(temp);
sleep(5000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
};
timer.start();
String username=scanner.nextLine();
String to=scanner.nextLine();
String body=scanner.nextLine();
Message all=new Message();
all.setText(body);
all.setReceiver(to);
all.setSender(username);
System.out.println("you connected to system");
System.out.println(socket);
System.out.println("now should write");
out.writeObject(all);
System.out.println("ghable threAD");
}
// socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.out.println("salaam c");
System.out.println(e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("bye c");
System.out.println(e.getMessage());
}
}
else
{
System.out.println("bad operation. try again!");
}
}
}
Message class(Entity only not important i think!):
import java.io.Serializable;
public class Message implements Serializable{
String sender;
String receiver;
String text;
boolean delivered=false;
public void delived()
{
this.delivered=true;
}
private String tostringOfClass;
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public void setSender(String sender) {
this.sender = sender;
}
public void setText(String text) {
this.text = text;
}
public String getReceiver() {
return receiver;
}
public String getSender() {
return sender;
}
public String getText() {
return text;
}
public String toString()
{
tostringOfClass="sender : "+sender+" \n"+"receiver : "+receiver+" \n"+"message: "+text;
return tostringOfClass;
}
}

Your evaluator missed something much more important: it doesn't work. You are calling readObject() twice per loop in the server, but all you do with the first result is print it out with System.out.println(). So your code is missing every odd object.
There isn't much you could do to improve the speed of this. He probably wants you to interpose a BufferedOutputStream between the ObjectOutputStream and the socket, and similarly for BufferedInputStream. However the object streams already run their own buffers, so this is probably a waste of time. He might also want you to use large socket send and receive buffers, if you've been taught about those: see Socket.setXXXBufferSize(). Set them to at least 32k. He might also be anti-Serialization, but for this application I don't see that it makes much difference. This is an interactive application, and the messages are small, so the speed over the network is basically irrelevant. You can only type so fast.
You should also close in the client when the user types whatever it is that tells the program to stop, and in the server you must catch EOFException, before IOException, and close the socket and break out of the read loop when you get it.
Also printing out Socket.isConnected() yields no useful information. The socket is always connected at the points you print it at. This method is not a health-check for the connection, it only tells you about the state of your Socket. Not the same thing.
Your evaluator seems to me to be focussing on entirely the wrong thing.

I'm not sure how much time you would want to invest in optimizing your Socket code, but ZMQ http://www.zeromq.org/ has helped greatly in removing latency and optimizing the Bandwidth usage.
However, in simpler notes. Try not to use ObjectOutputStream they are one layer above. Go immediately for DataInputStream and DataOutputStream (Maybe also BufferedInputStream) It's been a while for me, so I'm rusty. But since you are sending strings, you don't need to do Object Serialization along with it.
You said, your time is being lost in data transfer as well. But consider not creating a new thread on each connection and use thread pools.
and Salam.

Related

Is there any way to delay Async NIO server response in Java?

Having trouble 'delaying' the response of server, which is passed to client side.
What I'm trying to do is, just make an echoing, asynchronous, Non-blocking server with NIO package.
Then, I want to manually delay the response sent to Client, to confirm that this server handles multiple response, while not blocked by any of its clients, delays observable by naked eyes.
The main server code is :
package AsyncServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import AsyncServer.AsyncHandler.*;
public class AsyncServer {
int port = 40000;
public AsyncServer () {}
public AsyncServer(int port) {this.port = port;}
protected void start()
{
System.out.println("Async Server running at port "+this.port);
try {
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(this.port));
AcceptCompletionHandler ach = new AcceptCompletionHandler(server);
server.accept(null, ach);
System.in.read();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
package AsyncServer.AsyncHandler;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {
private final AsynchronousServerSocketChannel ssc;
public AcceptCompletionHandler(AsynchronousServerSocketChannel in_ssc) {
this.ssc = in_ssc;
}
#Override
public void completed (AsynchronousSocketChannel sc, Void attachment) {
/*
This context was used in attempt to delay response sent to async client.
Does not work properly, only delaying server console output
try {
int amount = (int) (Math.random() * 20);
Thread.sleep(amount*1000);
System.out.println("slept for "+amount);
}
catch (InterruptedException e) {
e.printStackTrace();
}
*/
ssc.accept(null, this);
System.out.println("Connection Established");
ByteBuffer buffer = ByteBuffer.allocate(512);
ReadCompletionHandler rch = new ReadCompletionHandler(sc, buffer);
sc.read(buffer, null, rch);
//System.out.println("Received "+buffer.toString());
}
#Override
public void failed (Throwable T, Void attachment){
T.printStackTrace();
}
}
package AsyncServer.AsyncHandler;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.*;
public class ReadCompletionHandler implements CompletionHandler<Integer, Void> {
private final AsynchronousSocketChannel sc;
private final ByteBuffer buffer;
ReadCompletionHandler (AsynchronousSocketChannel in_sc, ByteBuffer in_buffer) {
this.sc = in_sc;
this.buffer = in_buffer;
}
#Override
public void completed (Integer bytes, Void attachment) {
WriteCompletionHandler wch = new WriteCompletionHandler(this.sc);
this.buffer.flip();
this.sc.write(this.buffer, null, wch);
Charset charset = Charset.forName("UTF-8");
String outputStr = new String(this.buffer.array()).trim();
System.out.println("Writing "+outputStr+" into return buffer");
}
#Override
public void failed (Throwable T, Void attachment) {
T.printStackTrace();
}
}
package AsyncServer.AsyncHandler;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class WriteCompletionHandler implements CompletionHandler<Integer, Void> {
private final AsynchronousSocketChannel sc;
WriteCompletionHandler (AsynchronousSocketChannel in_sc) {
this.sc = in_sc;
}
#Override
public void completed (Integer bytes, Void attachment) {
try {
sc.close();
System.out.println("Socket closed");
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void failed (Throwable T, Void attachment) {
T.printStackTrace();
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class AsyncClient {
private String ip = "localhost";
private int port = 40000;
private String payload = "00209999997778222223";
AsyncClient(String in_ip, int in_port, String in_payload)
{
this.ip = in_ip;
this.port = in_port;
this.payload = in_payload;
}
AsyncClient() {}
void start()
{
try {
AsynchronousSocketChannel sc = AsynchronousSocketChannel.open();
SocketAddress serverAddr = new InetSocketAddress(this.ip, this.port);
Future<Void> res = sc.connect(serverAddr);
System.out.println("Will connect to remote");
res.get();
System.out.println("Connection Established");
String outStr = this.payload;
ByteBuffer buffer = ByteBuffer.wrap(outStr.getBytes());
Future<Integer> sender = sc.write(buffer);
sender.get();
buffer.flip();
Future<Integer> receiver = sc.read(buffer);
System.out.println("Received : "+new String(buffer.array()).trim());
receiver.get();
buffer.clear();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
}
}
Client Code components are also available in here.
So this code calls on Custom completionHandler three times.
Control flow goes to AcceptCompletionHandler -> ReadCompletionHandler -> WriteCompletionHandler, when each accept, read, write is called.
As I mentioned earlier, what I wanted to achieve was delaying whole asynchronous receive-response stream of each client thread. By running Client code on multiple threads, Say, some delays 11s, other delay less than 10s, my bare eye could catch this asynchronous operation.
However, If I run multiple threads of AsyncClient, It appears that no delay happens. Almost Instantly, the response arrives at client side. However, delays are really delaying console output of server side. Like this one. Sorry for missing timestamps!
I added semaphore acquire&release to server object itself, wrap delay syntax with semaphore acquire&release. It seems that asyncSocketStream passes their work to any other Idle thread if it meets delay. So I wrapped whole server in ExecutorService package, limiting maximum thread to one. Still, the client gets its reponse right away, and meaningless waiting of server console output happens...
Please enlighten me if I'm doing what is very bad, since I'm new to Async socket programming.

Java Object streams to libGDX project

i did try to test some stuff about Client/server communication in Java because i wanted to build a game with a client/server architecture.
So i read some articles and so on... it all worked till i tried to use the same classes and methods in a libGDX project client and the other as server was still the original java project.
than the fun started and i got class not found exceptions on the server side when the server where trying to read the object.
after that i tried to build client and server both as libGDX projects.
still the same error.
the serve:
package com.mygdx.game;
import java.io.IOException;
import java.net.*;
public class Server {
public static void main(String[] args) {
int port = 8800;
try {
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
System.out.println("raedy");
Socket clientSocket = serverSocket.accept();
System.out.println(clientSocket+"verbunden!");
Worker worker = new Worker(clientSocket);
worker.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.mygdx.game;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Worker extends Thread{
private Socket clientSocket;
public Worker(Socket clientsocket) {
this.clientSocket = clientsocket;
}
#Override
public void run() {
System.out.println("worker started");
try {
ObjectInputStream in= new ObjectInputStream(clientSocket.getInputStream());
Object obj = (Object) in.readObject();
if(obj instanceof Message) {
Message msg= (Message) in.readObject();
System.out.println("Client said: "+msg.getMessage());
}
System.out.println("input auf"+clientSocket.getLocalPort());
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
out.writeObject(new Message("Hello there!"));
System.out.println("output auf"+clientSocket.getPort());
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.mygdx.game;
import java.io.Serializable;
public class Message implements Serializable{
private static final long serialVersionUID = 1L;
private String message;
public Message(String message) {
this.message = message;
}
public String getMessage(){
return message;
}
}
the client has the the same Message class and this:
package com.mygdx.game.desktop;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.mygdx.game.MyGdxGame;
public class DesktopLauncher {
public static void main (String[] arg) {
int port = 8800;
try {
System.out.println("hello there!");
Socket client = new Socket("localhost", port );
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(new Message("ich bin der client"));
System.err.println(client.getPort());
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
Message msg= (Message) in.readObject();
System.out.println("Server said: "+msg.getMessage());
System.out.println(client.getLocalPort());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
new LwjglApplication(new MyGdxGame(), config);
}
}
so my question is why does the same code work in normal java but when i build the same as a libGDX project and try the code there it doesn't work?
yes the message class is only for testing how a serializable object is transferred.
Later i want to send game commands via the object stream.
ps: you made it till the end! thank you :D
pps: the first try in java was without
Object obj = (Object) in.readObject();
if(obj instanceof Message)
I would really recommend you to use Kryonet instead of writing all the stuff from scratch yourself. It does exactly what you are trying to achieve, is mature and well tested with libGDX.

Server Socket blocks after first recived data

I want to ask why the server is showing only the first time one of the clients send data ,my intent is to have two clients and just want to send some integer ,the server to read it and then send it back to the other client and then to wait the this client to send info and send it to the other client (toggling them).But only the first time the data is sended ,it is read on the server ?
Server :
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serv;
private DataInputStream inFromClient1;
private DataOutputStream outToClient1;
private DataInputStream inFromClient2;
private DataOutputStream outToClient2;
public Server(){
try {
serv=new ServerSocket(8000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void listen() throws IOException{
System.out.println("Listening for connections");
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
Socket sock1;
Socket sock2;
try {
sock1 = serv.accept();
sock2=serv.accept();
handleSession(sock1,sock2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
public void handleSession(Socket s1,Socket s2) throws IOException{
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
while(true){
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
int inint2=in2.readInt();
System.out.println("Recived from 2 " + inint2);
System.out.println("Sending to 1 ");
out1.writeInt(inint2);
}
}
public static void main(String[] args) throws IOException {
new Server().listen();
}
}
Client :
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Client extends JFrame implements ActionListener{
private JPanel mainPanel;
private JButton[] buttons;
private Socket socket;
private int number;
private DataInputStream fromServer;
private DataOutputStream toServer;
private boolean myTurn=true;
public Client() throws UnknownHostException, IOException{
mainPanel=new JPanel(new GridLayout(3,3));
socket=new Socket("localhost",8000);
add(mainPanel);
addbuttons();
setSize(new Dimension(500,400));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void addbuttons(){
buttons=new JButton[9];
for(int i=1;i<10;i++){
buttons[i-1]=new JButton("Rectangle " + i);
buttons[i-1].addActionListener(this);
mainPanel.add(buttons[i-1]);
}
}
public void actionPerformed(ActionEvent arg0) {
JButton butt=(JButton) arg0.getSource();
String str=butt.getText();
String[] splitStr=str.split(" ");
number=Integer.parseInt(splitStr[1]);
System.out.println(number);
}
public void start() throws IOException{
fromServer=new DataInputStream(socket.getInputStream());
toServer=new DataOutputStream(socket.getOutputStream());
new Thread(new Runnable() {
#Override
public void run() {
Scanner in=new Scanner(System.in);
while(true){
System.out.println("Write some integer");
int inint=in.nextInt();
System.out.println("Before " + myTurn);
if(myTurn){
try {
toServer.writeInt(inint);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myTurn=false;
}
else{
int fromServint=0;
try {
fromServint=fromServer.readInt();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Recived integer " + fromServint);
buttons[fromServint].setText("Some new Text");
myTurn=true;
}
System.out.println("After " + myTurn);
}
}
}).start();
}
public static void main(String[] args) throws UnknownHostException, IOException {
new Client().start();
}
}
Looks like you're reading 2 integers from client 1 (guessing it's a typo) so
try changing
out2.writeInt(in1.readInt());
to
out2.writeInt(inint1);
Also, as #JohnBollinger mentioned,
Separate Data*Streams are created, but both sets are connected to socket s1, instead of one set to each socket.
DataInputStream in1=new DataInputStream(s1.getInputStream());
DataOutputStream out1=new DataOutputStream(s1.getOutputStream());
DataInputStream in2=new DataInputStream(s1.getInputStream());
DataOutputStream out2=new DataOutputStream(s1.getOutputStream());
All streams here are referencing the same client.
You are using blocking sockets. For that reason, when you call any kind of "read" method, it will block until data is received from the client.
So, one thread is not enough. The first read will block, the second read will never be executed unless the first client actually sent something.
Solution 1: Use one thread per socket connection (recommended, because easier).
Solution 2: Use non-blocking sockets (not recommended, difficult but good for certain performance critical scenarios).
Look here:
int inint1=in1.readInt();
System.out.println("Recived from 1 " + inint1);
System.out.println("Sending to 2 ");
out2.writeInt(in1.readInt());
First you read an int from the first client. Then you print some stuff and read a second int from the same client. But the client waits for a int from the server and therefore sends no second, so the server blocks.
Replace the last line of the code above with out2.writeInt(inint1); and see if it works. I haven't read all of the code, so I am not sure if there is another mistake.

Continuously read objects from an ObjectInputStream in Java

I have a problem using an ObjectInputStream and I have been struggling with it for 2 days now. I tried to search for a solution but unfortunately found no fitting answer.
I am trying to write a client/server application in which the client sends objects (in this case a configuration class) to the server. The idea is that connection keeps alive after sending the object so it is possible to send a new object if necessary.
Here are the important parts of my client code:
mSocket = new Socket("192.168.43.56", 1234);
mObjectIn = new ObjectInputStream(mSocket.getInputStream());
mObjectOut = new ObjectOutputStream(mSocket.getOutputStream());
mObjectOut.writeObject(stubConfig);
mObjectOut.flush();
In the above code, I left out some try/catch blocks to keep the code readable for you.
The server side looks as follows:
mHostServer = new ServerSocket(port);
mSocket = mHostServer.accept();
// create streams in reverse oreder
mObjectOut = new ObjectOutputStream(mConnection.getOutputStream());
mObjectOut.flush();
mObjectIn = new ObjectInputStream(mConnection.getInputStream());
while (mIsSocketConnected)
{
StubConfig = (StubConfiguration)mObjectIn.readObject();
}
What I want to achieve is that as long at the socketconnection is alive, the server is listening for incoming config objects.
When I run my program however, I got an EOFException in the while loop at server side. I receive the first config object without any problems in the first iteration of the while loop but after that I get an EOFException every time readObject() is called.
I am looking for a way to solve this. Can anyone put me in the good direction?
EDIT: What I read about the EOFException is that it is thrown when you want to read from a stream when the end of it is reached. That means that for some reason the stream ended after the object has been send. Is there a way to reinitialize the streams or so??
EOFException is thrown by readObject() when the peer has closed the connection. There can never be more data afterwards. Ergo you can't have written multiple objects at all: you closed the connection instead.
try using this
Server side
1.Server running on a separate thread
public class ServeurPresence implements Runnable {
public final static int PORT = 20000 ;
public final static String HOSTNAME = "localhost" ;
public static enum Action {CONNEXION, MSG, DECONNEXION,USER, FINCLASSEMENT};
ServerSocket serveur ;
static List<String> names ;
*/
public ServeurPresence()
{
System.out.println("Start Server...");
try
{
serveur = new ServerSocket(PORT) ;
new Thread(this).start();
//javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI();} } );
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* #param args
*/
public static void main(String[] args)
{
new ServeurPresence();
}
#Override
public void run()
{
System.out.println("server runs");
while(true)
{
try {
Socket sock = serveur.accept();
ServiceClientsThread thread= new ServiceClientsThread(sock);
thread.start();
}
catch (IOException e)
{
System.out.println("Error with socket");
e.printStackTrace();
}
}
}
}
2. A Thread to handle each Client:ServiceClientThread
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ServiceClientsThread extends Thread{
private Socket sock ;
ServiceClientsThread(Socket sock)
{
//super();
this.sock=sock;
}
#Override
public void run()
{
DataInputStream is ;
DataOutputStream os ;
String name =null ;
try {
is = new DataInputStream(sock.getInputStream()) ;
os = new DataOutputStream(sock.getOutputStream()) ;
ServeurPresence.Action act ;
do {
// read Action
act = ServeurPresence.Action.valueOf(is.readUTF()) ; // read string -> enum
System.out.println("action :"+act);
switch (act) {
case CONNEXION :
name = is.readUTF(); //read client name
System.out.println("Name :"+name);
os.writeUTF("Hi");//send welcome msg
break ;
case MSG :
String msg = is.readUTF();
os.writeUTF("OK");//response
break ;
case DECONNEXION :
System.out.println(name+" is logged out");
break ;
}
} while (act!=ServeurPresence.Action.DECONNEXION) ;
// the end
is.close();
os.close();
sock.close();
} catch (IOException e)
{
System.out.println("Error with "+name+" socket");
e.printStackTrace();
}
}
}
3. Client side
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
/**
*
*/
Client(String name)
{
System.out.println("Start Client...");
try {
Socket sock = new Socket(ServeurPresence.HOSTNAME,ServeurPresence.PORT) ;
DataOutputStream os = new DataOutputStream(sock.getOutputStream()) ;
DataInputStream is = new DataInputStream(sock.getInputStream()) ;
System.out.println("Send "+name+" to server");
// CONNECTION : Action then value
os.writeUTF(ServeurPresence.Action.CONNEXION.name()) ; // send action : write enum -> String
os.writeUTF(name) ; // send the name
//read server welcome msg
String msg = is.readUTF();
System.out.println("Welcome msg: "+msg);
/* Your actions here : see example below */
try
{
Thread.currentThread().sleep(4000);
os.writeUTF(ServeurPresence.Action.MSG.name()) ; // send action : write enum -> String
os.writeUTF("My message here") ; // send msg
Thread.currentThread().sleep(4000);
msg = is.readUTF();//server response message
}
catch (InterruptedException e)
{
e.printStackTrace();
}
/************************************************/
//CLOSE
os.writeUTF(ServeurPresence.Action.DECONNEXION.name()) ; // send action
System.out.println("Log out");
os.close();
sock.close();
}
catch (UnknownHostException e)
{
System.out.println(ServeurPresence.HOSTNAME+ " unknown");
e.printStackTrace();
}
catch (IOException e)
{
System.out.println("Impossible to connect to "+ServeurPresence.HOSTNAME+ ":"+ServeurPresence.PORT);
e.printStackTrace();
}
}
}
4. In your case use readObject()/writeObject() instead of readUTF()/writeUTF() to write your config objects
Try this and let me know how it goes:
while (1==1)
{
StubConfig = (StubConfiguration)mObjectIn.readObject();
Thread.sleep(100); //Saves CPU usage
}
Very late answer, but just for future reference. I have been having problems sending Objects via sockets because the method flush() is not working properly.
I solved this problem just by switching flush() to reset().

NullPointerException in Thread's run method

I would really appreciate help with my program. It is some sort of chat server with multiple clients.
Here's the server code:
package com.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static int PORT;
private ServerSocket server;
private Socket socket;
public Server(int port) throws IOException {
PORT = port;
server = new ServerSocket(PORT);
System.out.println("server started");
try {
while (true) {
socket = server.accept();
try {
new ServeClient(socket);
} catch (IOException e) {
socket.close();
}
}
} finally {
server.close();
}
}
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
}
}
I start the server and then create a Client. The server receives connection socket from socket
and creates a ServeClient Thread.
Here's ServeClient code:
package com.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import com.gui.WindowManager;
public class ServeClient extends Thread {
private final Socket socket;
private BufferedReader in;
private PrintWriter out;
private String msg;
public static final String ENDSTRING = "END";
public static Vector clients = new Vector();
public ServeClient(final Socket socket) throws IOException {
this.socket = socket;
System.out.println("socket " + socket);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
start();
}
public void run() {
try {
clients.add(this);
while (true) {
msg = in.readLine();
if (msg == ENDSTRING)
break;
broadcast(msg);
}
System.out.println("closing...");
} catch (IOException e) {
System.err.println("IO EXCEPTION");
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("SOCKET NOT CLOSED");
}
}
}
#SuppressWarnings("deprecation")
public void broadcast(String msg) {
synchronized (clients) {
Enumeration<ServeClient> e = clients.elements();
while (e.hasMoreElements()) {
ServeClient serveClient = e.nextElement();
try {
synchronized (serveClient.out) {
serveClient.out.println(msg);
}
} catch (Exception eee) {
serveClient.stop();
}
}
}
}
}
What i get is a NullPointerException when ServeClient invokes run() method
server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
at com.server.ServeClient.run(ServeClient.java:33)
line 33 is the line with first "try" statement in ServeClient run() method
com.server.ServeClient.run(ServeClient.java:33)
I don't believe that it's happening at the try.
Open up an IDE, turn on debugging, and step through until you can see what's happening. That's the fastest way to figure out what you've missed.
There's an object that you're assuming is fine that is not. Find it.
Here's an example of how to do this properly:
http://www.kodejava.org/examples/216.html
Your problem is with the order in which static instance variables are initialised. Try doing something like:
...
private static Vector clients = null;
...
if (clients==null) {
clients = new Vector(); // consider putting this in a synchronized block
}
before you add the client to the vector.
Sorry for necroing such an old issue but it seemed like this problem wasn't resolved, so I'll give a bit of input from my end.
I've had a similar problem and the compiler also kept telling me that the problem was at the start() method. However, when I commented out the thread part and just ran the code on the same thread as the UI, the compiler directed me to the real source of the problem: the code inside the thread.
After making sure the code didn't give an error, I enclosed the code with the original thread code, and it stopped giving me the NullPointerException error.
Hope this helps someone along the way.
Remove the duplicate class declaration in JPanel.
I was trying to run a timer thread that updated a clock in the main application window.
I had created the JFrame with Eclipse/WindowBuilder and had followed a tutorial on how to make a timer. I had copied the declaration of the textfield into the class declaration to make it available for the entire class, but forgot to remove the Class Id in front of the widget definition. So it still initialized the local instance and not the global one. Thus when I accessed the global one it was still null.

Categories

Resources