I am a beginner in Java. I have built a client-server group chat application watching tutorials. I read a lot about unit tests and can implement in simple maths problems but i don't know how does it work out for complex codes. So I want to see a demo of that which will make it easy to understand testing for rest parts. One part of the code is the 'server' class and it is:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//import java.awt.event.*;
public class Server {
private final ServerSocket s;
public Server(ServerSocket serverSocket)
{
this.s = serverSocket;
//this.display = display;
}
public void startServer() {
try {
// Listen for connections (clients to connect) on port 1234.
while (!s.isClosed()) {
// Will be closed in the Client Handler.
Socket socket = s.accept();
System.out.println("A new client has connected!");
ClientHandler clientHandler = new ClientHandler(socket);
Thread thread = new Thread(clientHandler);
// The start method begins the execution of a thread.
// When you call start() the run method is called.
// The operating system schedules the threads.
thread.start();
}
} catch (IOException e) {
closeServerSocket();
}
}
// Close the server socket gracefully.
public void closeServerSocket() {
try {
if (s != null) {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Run the program.
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(1234);
Server server = new Server(s);
server.startServer();
}
}
and the test I want to perform are:
import static org.junit.Assert.*;
public class ServerTeste {
#org.junit.Test
public void startServer() {
}
#org.junit.Test
public void closeServerSocket() {
f
}
}
#org.junit.Test
public void main() {
}
}
NB: Apologies for any mistake because I am complete beginner.
Start the server in a separate thread, and connect to it like you would normally do
Related
I have a class A that accepts TCP connection and send this new socket to Thread B where data from that socket is received and sent.
Class A{
Class b = new B();
public void run()
{
b.start();
while(true){
Socket socket = serverSocket.accept();
if(socket==null || socket.isClosed())continue;
b.setSocket(socket);
}
}
}
Class B extends Thread{
Socket socket;
public void setSocket(Socket p_socket) throws IOException
{
if(socket!=null && !socket.isClosed())
{
try{
socket.close();
socket = null;
Thread.sleep(5);
}
catch(Exception ex)
{}
}
socket = p_socket;
inputStream = socket.getInputStream(); // Here I am getting socket.closed() exception very much.
}
This worked fairly good in the past but now recently I am very very frequently getting the following error.
java.io.IOException: Socket Closed
at java.net.AbstractPlainSocketImpl.getInputStream(AbstractPlainSocketImpl.java:421)
at java.net.Socket$2.run(Socket.java:914)
at java.net.Socket$2.run(Socket.java:912)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.Socket.getInputStream(Socket.java:911)
I don't understand why this is happening now after years of working fine. Is this due to the network problem or Thread related something?
Updated:
Can this be the server related problem? Because the same application is running on other server but they are not having this problem.
The whole setup concept looks a bit broken. You should not "change" resources from the outside, while maybe there is still some work going on in that thread. A way better concept is to encapsulate the Socket into a new worker thread:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class WrapHandler {
static public class Server {
private final ServerSocket mSocket;
private final ArrayList<Handler> mRunningHandlers = new ArrayList<>();
public Server(final int pPort) throws IOException {
mSocket = new ServerSocket(pPort);
new Thread(() -> mainLoop()).start();
}
private void mainLoop() {
while (true) {
try {
#SuppressWarnings("resource") final Socket socket = mSocket.accept(); // do not close, do not handle with resource, socket will be closed by handler!
final Handler h = new Handler(socket, this);
handlerStarted(h);
} catch (final IOException e) {
e.printStackTrace(); // do something useful
}
}
}
synchronized void handlerStarted(final Handler pHandler) {
mRunningHandlers.add(pHandler);
}
synchronized void handlerEnded(final Handler pHandler) {
mRunningHandlers.remove(pHandler);
}
void handleException(final Handler pHandler, final Throwable pException) {
/* again do something useful */
}
}
static public class Handler {
private final Socket mSocket;
private final Server mServer;
public Handler(final Socket pSocket, final Server pServer) {
mSocket = pSocket;
mServer = pServer;
new Thread(() -> handleSocket()).start();
}
private void handleSocket() {
try {
handleData();
} catch (final IOException e) {
mServer.handleException(this, e);
} finally {
mServer.handlerEnded(this);
stop();
}
}
private void handleData() throws IOException {
mSocket.getInputStream().read();
/* data handling code here */
}
void stop() {
try {
mSocket.close();
} catch (final IOException e) { /* ignore or handle as you will */ }
}
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Hi all :) Sorry for this really long question but this needs some explaination.
I was given an assignment where i have to turn a very simple game into a 2 player multiplayer game. The reason why we have to make this game is to learn more about threads and concurrency. I have never worked with concurrency nor with multiple threads.
My idea is to create a TCP server like i have done in GameServer.java where i create a new ServiceObject for each player. I create a thread for each ServiceObject where i will recieve, handle and send commands from a client.
Gameserver.java
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class GameServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(6789);
System.out.println("Waiting for clients to connect . . . ");
Socket s1 = server.accept();
System.out.println("Clients connected.");
PlayerService servicep1 = new PlayerService(s1);
Thread t1 = new Thread(servicep1);
Socket s2 = server.accept();
System.out.println("Clients connected.");
PlayerService servicep2 = new PlayerService(s2);
Thread t2 = new Thread(servicep2);
t1.start();
t2.start();
servicep1.sendDataToClient("ready");
servicep2.sendDataToClient("ready");
}
}
PlayerService.java
package server;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
import game2016.Player;
public class PlayerService extends Thread {
private Socket s;
private PlayerService opponent;
private Scanner in;
private PrintWriter out;
public PlayerService(Socket aSocket) {
this.s = aSocket;
}
public void setOpponent(PlayerService opponent) {
this.opponent = opponent;
}
public void run() {
try {
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
try {
doService();
} finally {
// s.close();
}
} catch (IOException exception) {
exception.printStackTrace();
}
}
public void doService() throws IOException {
while (true) {
if (!in.hasNext()) {
return;
}
String command = in.next();
if (command.equals("QUIT")) {
return;
} else
recieveFromClient(command);
}
}
public void recieveFromClient(String command) throws IOException {
System.out.println(command);
if(command.equals("player")) {
String newPlayerName = in.next();
int xPos = in.nextInt();
int yPos = in.nextInt();
String direction = in.next();
// sendDataToOpponent("addOpponent " + newPlayerName + " " + xPos + " " + yPos + " " + direction);
}
}
public void sendDataToClient(String response) {
out.write(response + "\n");
out.flush();
}
public void sendDataToOpponent(String response) {
opponent.sendDataToClient(response);
}
}
To send data from one client to another client i have a reference to the opponents servicelayer as i can invoke the sendDataToOpponent() method to send data to him and if the server have to communicate i can just invoke sendDataToClient() from the server.
My problem is that i want to postpone opening my clients GUI to both clients have connected.
Main.java(Client) - GUI code have been left out
private static Socket s;
private static InputStream instream;
private static OutputStream outstream;
private static Scanner in;
private static PrintWriter out;
private static boolean isOpponentConnected;
public static void main(String[] args) throws Exception {
openConnection();
reciever();
waitOpponentConected();
launch(args);
}
public static void waitOpponentConected() throws Exception {
while(!isOpponentConnected) {
System.out.println("Waiting for opponent");
Thread.sleep(2000);
}
System.out.println("Opponent is ready now");
}
public static void openConnection() throws IOException {
s = new Socket("localhost", 6789);
System.out.println("Connection established");
instream = s.getInputStream();
outstream = s.getOutputStream();
in = new Scanner(instream);
out = new PrintWriter(outstream);
}
public static void responseFromServer() throws IOException {
try {
while(in.hasNext()) {
String response = in.next();
if(response.equals("ready")) {
isOpponentConnected = true;
System.out.println("Ready");
}
}
} catch (Exception e) {
}
}
public static void reciever() {
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
while(true) {
responseFromServer();
}
}
};
new Thread(task).start();
}
public static void sendCommandToServer(String command) throws IOException {
out.print(command + "\n");
out.flush();
}
I've created a Thread to recieve commands from the server, and when both clients have connected to the server it sends a string 'ready' to each of the clients. My thought was that The Main-thread sleeps till isOpponentConnected is true.
But my gameserver fails and prints out a nullpointer exception when the second clients connects to the server. I've spend to days reading and trying to fix this bug. When i run the code in debug mode, both clients recieves the ready signal and the GUI starts for both clients.
Exception in thread "main" java.lang.NullPointerException
at server.PlayerService.sendDataToClient(PlayerService.java:67)
at server.GameServer.main(GameServer.java:23)
Can you guys see anything i'm obviously doing wrong?
I think this queston is interesseting because it's not just the nullpointerexception, it's about structering TCP server-client relationships and the chain when things are initialized and ready when threads and connections are made.
It should be fixable from inside the PlayerService.java class you have posted.
I suggest moving:
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
from public void run() to your PlayerService constructor:public PlayerService(Socket aSocket)
It looks like the function sendDataToClient is trying to use the out variable before it gets initialised.
I'm facing a strange problem doing java sockets project. Here's my code:
Server:
package second.sockets;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server implements Runnable {
public static String HOST = "localhost";
public static int PORT = 1234;
private static final int MAX_USERS = 2;
private static final Server serverInstance = new Server();
private ServerSocket serverSocket;
private List<User> users = new ArrayList<>();
private Server() {
try {
if( this.serverSocket == null ) {
this.serverSocket = new ServerSocket(Server.PORT);
}
} catch(IOException e) {
e.printStackTrace();
System.err.println("could not initialize ServerSocket on port="+Server.PORT +
"["+ e.getMessage() +"]");
}
}
public static Server getInstance() {
return Server.serverInstance;
}
#Override
public void run() {
System.out.println("waiting for incoming connections...");
try {
while( !Thread.interrupted() ) {
this.waitForFreeSlots();
Socket newSocket=null;
try {
newSocket = this.serverSocket.accept();
System.out.println("new connection " + newSocket);
} catch(IOException e) {
System.err.println("could not connect");
}
}
} catch(InterruptedException e) {
System.err.println("server interrupted");
}
}
private synchronized void waitForFreeSlots() throws InterruptedException {
while( this.users.size() >= Server.MAX_USERS ) {
this.wait();
}
}
public static int getPORT() {
return PORT;
}
public static void main(String[] args) {
Server server = Server.getInstance();
Thread serverThread = new Thread(server);
serverThread.start();
}
}
Client:
package second.sockets;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
Socket socket=null;
try {
socket = new Socket(Server.HOST, Server.PORT);
} catch(UnknownHostException uhe) {
System.err.println("could not connect to "+Server.HOST+" on port "+Server.PORT+", no such host");
} catch(IOException ioe) {
System.err.println("could not connect to "+Server.HOST + " on port "+Server.PORT);
}
System.out.println(socket);
}
}
I run the server and it works, but when I run a Client I get could not initialize ServerSocket on port=1234[Address already in use: JVM_Bind] and it is from Server code from line 25. It's odd as Server is a singleton so there's no place for more than one instance of the class. What is more I don't even touch it in Client main function. I don't get it, any ideas where the problem is? Thanks.
EDIT:
Here's the stack trace. It comes from Server's constructor although it is private and it shows after running the Client.
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at second.sockets.Server.<init>(Server.java:22)
at second.sockets.Server.<clinit>(Server.java:15)
at second.sockets.Client.main(Client.java:12)
could not initialize ServerSocket on port=21234[Address already in use: JVM_Bind]
Socket[addr=localhost/127.0.0.1,port=21234,localport=53054]
I don't get this transition:
at second.sockets.Client.main(Client.java:12)->at second.sockets.Server.<clinit>(Server.java:15)
The stuff you see in the exception comes from the fact that you are using Server.HOST and Server.PORT in your client code. This calls the class initializer for the Server class. In this initializer all the static stuff in the Server class is created. And I see you have a static Server instance there...so you have in fact several Server instances created.
So avoid using Server.HOST and Server.PORT in the client code and use the real valus directly and it will work.
Normally when you want to share stuff between 2 code entities, move them to a third entity to decouple the server and client. Then let server and client use that new entity.
Okay, I figured out what was wrong. In Client in this line socket = new Socket(Server.HOST, Server.PORT); I was using 2 variables from class Server. When I deleted it and pasted raw values or cahnge the variables to be final, it started to work. This is some wild magic.
I have a problem in running server-client program. When i run my server program , it keeps on running and never ends up. On other side, when i run my client program it throws an exception as shown below (my firewall is off).
The replies will be more than appreciated. Thanks
//Client Code
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
public void go()
{
try {
Socket s = new Socket("127.0.0.1", 4242);
InputStreamReader read = new InputStreamReader(s.getInputStream());
BufferedReader z = new BufferedReader(read);
String advice = z.readLine();
System.out.println("today you should" + advice);
z.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
DailyAdviceClient x = new DailyAdviceClient();
x.go();
}
}
//Server Code
import java.io.*;
import java.net.*;
public class DailyAdvisor
{
String[] advicelist = { "take your time", "be patient",
"don't be diplomatic", " life is really short", "try to fix things" };
public void go()
{
try
{
ServerSocket s = new ServerSocket(4242);
while (true)
{
Socket m = s.accept();
PrintWriter writer = new PrintWriter(m.getOutputStream());
String advice = getAdvice();
writer.println(advice);
writer.close();
writer.flush();
System.out.println(advice);
}
} catch (IOException ex)
{
ex.printStackTrace();
}
}
private String getAdvice()
{
int random = (int) (Math.random() * advicelist.length);
return advicelist[random];
}
public static void main(String[] args)
{
DailyAdvisor x = new DailyAdvisor();
x.go();
}
}
The Server never ends up because you used a while(true) loop. It is necessary for your server to keep listening to new client connections through the accept() method.
About the exception, your code runs fine both locally and using a remote machine. Thus a network configuration error could be the cause and you must check if both server/client could see each other using the ping command. If this is the case, then check if the server is listening to the client using netstat.
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.