I have the follwing code which is a thread pool in java which accepts only one client
public class ServerThread implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
protected boolean isStopped = false;
int serverPort = 6500;
private String serverIpAddress = "127.0.0.1";
DataInputStream is;
ObjectOutputStream os=null;
protected BlockingQueue queue = null;
protected ExecutorService threadPool2 =
Executors.newFixedThreadPool(1);
public ServerThread(BlockingQueue queue) {
this.queue=queue;
}
public void run() {
try {
InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.bind(serverAddr);
System.out.println("s-a creat");
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
e.printStackTrace();
}
while(!isStopped()){
clientSocket=null;
try{
clientSocket = serverSocket.accept();
}
catch(Exception e)
{
e.printStackTrace();
}
WorkerServerRunnable workerRunnable = new WorkerServerRunnable(queue,clientSocket);
this.threadPool2.execute(workerRunnable);
}
this.threadPool2.shutdown();
System.out.println("Server Stopped.");
}
private synchronized boolean isStopped(){
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
}
But the problem is that I cannot get my server in ON state.
I mean once I press run I get the following error:
java.net.SocketException: Socket is not bound yet
at java.net.ServerSocket.accept(Unknown Source)
at servers.ServerThread.run(ServerThread.java:60)
at java.lang.Thread.run(Unknown Source)
java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at servers.ServerThread.run(ServerThread.java:44)
at java.lang.Thread.run(Unknown Source)
Even if I shutdown my whole app and run it again still the same error....has anyone any idea why?Thank u!
Some other program is already using port 6500. Check that you're not running another instance of your program.
Try running
netstat -lp
to see what processes are using which ports. Make sure the port on which you wish to listen is not listed in the output from netstat.
In the run() method, when you are creating a ServerSocket and assigning it to serverSocket variable:
serverSocket = new ServerSocket();
Please give a port number in the ServerSocket constructor, like 5000
serverSocket = new ServerSocket(5000);
Related
I have a server application that opens a socket and then listens to any connections being made on that socket.
public Server(){
try {
ServerSocket sSocket = new ServerSocket(nPort);
System.out.println("Server started at: " + new Date());
System.out.println("===============================================\n");
//Loop that runs server functions
while(true) {
//Wait for a client to connect
Socket socket = sSocket.accept();
socket.setSoTimeout(30000);
//Create a new custom thread to handle the connection
ClientThread cT = new ClientThread(socket, nPort);
//Start the thread!
new Thread(cT).start();
}
}
catch(IOException ex) {ex.printStackTrace();}
}
Whenever new connection attempted, a new thread is started using the ClientThread class. The ClientThread class has a run method that does all the things need to be done (read input, send respons etc.)
public class ClientThread implements Runnable{
private Socket threadSocket;
private int nPort = 0, maxCon = 2;
//This constructor will be passed the socket
public ClientThread_v3(Socket socket, int port){
threadSocket = socket;
nPort = port;
}
public void run(){
System.out.println("New connection at " + new Date() + "\n");
try {
DataInputStream in = new DataInputStream (threadSocket.getInputStream());
out = new DataOutputStream (threadSocket.getOutputStream());
while (running){
// do some stuff ....
// go to sleep
Thread.sleep(1000);
}
}
catch (IOException ex) {ex.printStackTrace();}
catch (InterruptedException ex) {ex.printStackTrace();}
finally {
try {
threadSocket.close();
System.out.println("Connection closed.\n");
} catch (IOException ex) {ex.printStackTrace();}
}
}}
My question is how do i make the socket connection secure? how do i open a secure connection?
I don't want to use any HTTP packages for that matter, want to keep it as a socket connection.
Any help would be appreciated. Thank you.
I had written a small code where I am trying to listen on particular port as follows (just trying out something) :
public class Test {
public static class MyThread extends Thread {
ServerSocket ss = null;
public MyThread(int port){
try {
ss = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Exception in assigning port : " + port);
e.printStackTrace();
}
}
public void stopListening(){
try {
ss.close();
} catch (IOException e) {
System.out.println("Exception in closing socket : " + ss.getLocalPort());
e.printStackTrace();
}
}
public void run(){
try {
ss.accept();
} catch (IOException e) {
System.out.println("Exception in listening on port : " + ss.getLocalPort());
e.printStackTrace();
}
}
}
public static void main(String[] args) {
List<MyThread> threadList = new LinkedList<>();
for (int i = 50000; i < 50005; i++) {
MyThread thread = new MyThread(i);
threadList.add(thread);
thread.start();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
for (MyThread myThread : threadList) {
myThread.stopListening();
}
}
}
But I am unable to start even a single thread , for every ss.accept() I keep getting :
Exception in listening on port :
I get the following exception in each case :
java.net.SocketException: socket closed
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at com.harman.hlacssmdw.Test$MyThread.run(Test.java:40)
I checked the ports from 50000 to 50000 using netstat -anp , none of theme are occupied.
I am unable to understand what am I doing wrong, Please help !!!
The ServerSocket is closed because you close it by calling stopListening(). That leads to an Exception for all Threads waiting on accept() of that ServerSocket.
I'm new in Java Sockets, I have seen so many examples but I can't understand how to pass an argument from server to client and vice versa. My destination is to pass an Object that's why I'm using Object I/O Stream.
I have to classes Server and Player.
public class Server extends Thread{
public static final int TEST = 165;
ServerSocket serverSocket;
InetAddress address;
Player playerWhite;
public Server() {
start();
}
#Override
public void run() {
try
{
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
playerWhite = new Player();
System.out.println("server waits for players");
playerWhite.socket = serverSocket.accept();
playerWhite.start();
sendTestMessage(playerWhite);
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendTestMessage(Player player) throws IOException
{
ObjectOutputStream testToClient = new ObjectOutputStream(player.socket.getOutputStream());
testToClient.write(TEST);
testToClient.flush();
}
And the Player class:
public class Player extends Thread {
Socket socket;
Player() throws IOException
{
socket = new Socket(InetAddress.getLocalHost(), 6000);
}
#Override
public void run() {
try {
listenTestStream();
}
catch (IOException | ClassNotFoundException ex)
{
Logger.getLogger(CheckerPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void listenTestStream() throws IOException, ClassNotFoundException
{
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
int message = ois.readInt();
//To test
System.out.println("Server listened: " + message);
}
I execute it as create a Server object in the other class.
When I have testing this application I saw that sometimes client is faster than Server. Is it possible to make him "wait" for server response?
Thanks for your response.
EDIT 1: PROBLEM SOLUTION:
From outside we should create:
Player player = new Player(); // (class player extends from Thread)
player.start();
and delete the Player variable - is not necessary, we need only Socket so:
Server:
Socket playerWhiteSocket
public void run() {
try
{
serverSocket = new ServerSocket(PORT);
playerWhiteSocket = serverSocket.accept();
sendMessage(playerWhiteSocket, "Hello");
}
catch(IOException | ClassNotFoundException ex)
{}
public void sendMessage(Socket socket, String message) throws IOException
{
ObjectOutputStream testToClient = new ObjectOutputStream(socket.getOutputStream());
testToClient.writeObject(message);
testToClient.flush();
}
In Player class we need get method:
public String receiveMessage() throws IOException, ClassNotFoundException
{
//socket is a variable get from Player class socket = new Socket("severHost", PORT);
ObjectInputStream messageFromServer = new ObjectInputStream(socket.getInputStream());
String message = (String) messageFromServer.readObject();
return message;
}
I would recomment doing this public void start(){
try {
ServerSocket = new ServerSocket(this.port,10,this.localAddress);
// set timeout if you want
//this.clientServerSocket.setSoTimeout(timeout);
// infinity loop
while(true)
{
//wait for a client connection
Socket socket = ServerSocket.accept();
// start thread for every new client
Thread t = new Thread(new AcceptClients(this.socket));
t.start();
System.out.println(L"new client connected");
// call garbage collector and hope for the best
System.gc();
}
} catch (IOException e) {
System.out.println("IO Error");
e.printStackTrace();
}
}
and then in another class
public class AcceptClients implements Runnable{
// socket
private Socket socket;
public AcceptClients (Socket socket){
this.socket = socket;
}
#Override
public void run() {
// what happens if a client connect
}
}
I always use this and it works fine
Suggested changes.
Create ServerSocket only once. If you have done it, you won't get "Address already in use" error
After creating Server Socket, you thread should be in while (true) loop to accept connection from client.
Once you create a client socket, pass that socket to thread.
Now Player is used to send communication from server to client socket. So You need one more class like PlayerClient which create a socket to Server IP and Port. Now PlayerClient should create one more thread to handle IO operations like you have done from server. In this case, creating a socket is not in while loop from client side. It create a socket to server once. Now you can run this PlayerClient program from multiple machines.
If you are just sending just primitive type, use DataOutputStream & DataInputStream instead of ObjectStreams
This code will become like this
try
{
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
System.out.println("server waits for players");
while ( true){
Socket socket = serverSocket.accept();
Player playerWhite = new Player(socket);
sendTestMessage(socket);// Move this method to Player thread and change the signature of this method accordingly to accept a socket
}
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
Player.java
Player(Socket socket) throws IOException
{
this.socket = socket;
start();
}
Have a look at this chat example for better understanding.
Yep it is.
It should work if you put it in a endlees loop like that:
try
{
while(true){
address = InetAddress.getLocalHost();
serverSocket = new ServerSocket(6000);
playerWhite = new Player();
System.out.println("server waits for players");
playerWhite.socket = serverSocket.accept();
playerWhite.start();
sendTestMessage(playerWhite);
}
}
catch (IOException ex)
{
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
But I would not recommend to put this in a thread. Instead I would put the connection of a new client in a thread, so multiple clients can connect to the server
I am trying to write a program in which the client requests the number of cores the server has. I do this as follows:
Client:
public void actionPerformed(ActionEvent e) {
try {
Socket clientSocket = new Socket("128.59.65.200", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String numberOfCores = inFromServer.readLine();clientSocket.close();
System.out.println(numberOfCores);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
Server:
public static void sendNumberOfCores() {
Thread coresThread = new Thread() {
public void run() {
try {
int numberOfCores;
ServerSocket welcomeSocket = new ServerSocket(6789);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
numberOfCores = Runtime.getRuntime().availableProcessors();
outToClient.write(numberOfCores);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
coresThread.setName("Wait for core request thread");
coresThread.start();
}
However, when I load the server and hit the button on my gui which runs the client code, nothing happens and the button just gets stuck. What is causing this?
Thank you.
Server not initialized on the 6789 port and make sure you do that in a separate thread.
Some thing like this.
In Server class:
--Make an inner class say MyServer
class MyServer implements Runnable{
final int BACKLOG=10; //10 is the backlog,if your server wishes to serve requests.
final int PORT = 6789;
public void run(){
try {
ServerSocket serverSocket = new ServerSocket(PORT,BACKLOG); //10 is the backlog,if your server wishes to serve conncurrent requests.
while (true) {
Socket ClientConnetion = serverSocket.accept();
//Now whatever you want to do with ClientConnection socket you can call
}
} catch (Exception e) {
e.printStackTrace();
}
}
--Start this thread in you main server class
MyServer mys=new MyServer();
Thread r=new Thread(mys);
mys.start();
It ended up that I was sending an integer when the code on the client was waiting for a string.
I got a program which listens to connections from a client.
import java.io.*;
import java.net.*;
class SocketExampleServer {
public static void main(String [] args) throws Exception {
int port = 5665;
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting incoming connection...");
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
String x = null;
try {
while ((x = dis.readUTF()) != null)
{
System.out.println(x);
out.writeUTF(x.toUpperCase());
}
}
catch(IOException e)
{
System.err.println("Client closed its connection.");
}
catch(Exception e)
{
System.err.println("Unknown exception");
}
s.close();
ss.close();
dis.close();
out.close();
System.exit(0);
}
}
The things is that at this point
System.out.println(x);
out.writeUTF(x.toUpperCase());
only the second line is executed. If you swap the line once a gain only the second line is executed. What is the reason for that?
And one more thing when I run the program second time it throws this error:
Exception in thread "main" java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at SocketExampleServer.main(SocketExampleServer.java:9)
Once I change the port number to a new one it runs for a one time and the next time you need to update the port number if you want to run it again. I did not get the reason for that cause I close the socket and in my opinion the port shall stay free for the next run up.
On the 2nd question:
Not sure what is causing that, but to avoid the possibility of a non-checked exception thrown by your code is the reason, you should close your resources in a finally clause:
ServerSocket ss;
try {
...
}
finally {
if (ss.close() != null) {
ss.close();
}
}