Parallel processing in Java Sockets not working properly - java

I have made two different programs for port Scanning. Both the programs use Threads but the thread distribution is different.
The first one uses single thread for single port, so it is not optimized for memory and time.
Here is the code :
import java.net.Socket;
import java.util.Scanner;
import java.lang.Exception;
import java.lang.Thread;
class helper{
public static void main(String []args){
Scanner s= new Scanner(System.in);
int port;
System.out.print("Enter web url :");
String url = s.next();
for(port=0;port<65536;port++){
helper2 h = new helper2(url,port);
h.start();
}
s.close();
}
}
class helper2 extends Thread{
int port;
String url;
helper2(String url,int port){
this.url=url;
this.port=port;
}
private void getStatus(){
try{
Socket skt = new Socket(url,port);
System.out.println(port);
skt.close();
}catch(Exception e){
//Handle Exception here
}
}
public void run(){
getStatus();
}
}
But in the other one I have 256 threads each having performing over 256 ports. It is faster.
Here is the other one :
import java.net.Socket;
import java.lang.Thread;
import java.util.Scanner;
import java.lang.Exception;
class helper {
public static void main(String []args){
Scanner s = new Scanner(System.in);
System.out.printf("Enter url :");
String url = s.next();
for(int i=0;i<256;i++){
helper2 h = new helper2(url,256*i);
h.start();
}
s.close();
}
}
class helper2 extends Thread {
int port ;
String url ;
helper2(String url, int port){
this.port=port;
this.url=url;
}
public void run(){
for(int i=0;i<256;i++){
try {
Socket skt = new Socket(url,i+port);
System.out.println(port+i);
skt.close();
} catch (Exception e) {
//TODO: handle exception
// System.out.print('j'); //for debugging
}
}
}
}
Both are working fine when url is given as localhost. But for other url like www.google.com second program does not behave correctly. Sometimes it does not produce any output and sometimes it throws OutOfMemory error and unable to create more threads. Please help.

Socket(String, int) tries to connect immediately, with no timeout (which means that it waits infinitely if the connection is not accepted by the server). At some hosts (including google.com), a connection to ports that are not specifically open will not be rejected automatically; instead, an attempt of such a connection will hang for some time, until it reaches a client-defined timeout (which is infinite in the case of Socket(String, int)).
I'd use Socket() constructor which does not connect automatically, and then connect manually passing some finite timeout:
Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 8888), 3000);

Related

How to close a server port after we are done using it?

Note: I found a similar question here:
How to close port after using server sockets
But did not find any satisfactory answer there.
Here is my code for the client program:
package hf;
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
private static final int chatPort = 4242;
public static void main(String[] args)
{
DailyAdviceClient client = new DailyAdviceClient();
client.go();
}
private void go()
{
try
{
Socket socket = new Socket("127.0.0.1",chatPort);
InputStreamReader inputStream = new InputStreamReader(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStream);
String advice = bufferedReader.readLine();
System.out.println("Advice received by the client for today is "+advice);
bufferedReader.close();
}
catch(Exception e)
{
System.out.println("Failed to connect to the server");
}
}
}
And here is the code for the server program:
package hf;
import java.io.*;
import java.net.*;
public class DailyAdviceServer
{
private String[] adviceList = {"Take smaller bites",
"Go for the tight jeans. No they do NOT make you look fat.",
"One word: inappropriate",
"Just for today, be honest. Tell your boss what you *really* think",
"You might want to rethink that haircut."};
private static final int chatPort = 4242;
public static void main(String[] args)
{
DailyAdviceServer server = new DailyAdviceServer();
server.go();
}
private void go()
{
try
{
ServerSocket serverSocket = new ServerSocket(chatPort);
while(true)
{
Socket socket = serverSocket.accept();
PrintWriter writer = new PrintWriter(socket.getOutputStream());
String advice = getTodaysAdvice();
writer.println(advice);
writer.close();
}
}
catch(Exception e)
{
System.out.println("Error in establishing connection with the client");
}
}
private String getTodaysAdvice()
{
String advice = null;
int randomIndex = (int) (Math.random()*adviceList.length);
advice = adviceList[randomIndex];
return advice;
}
}
In the application, whenever a client program connects to the server program, it receives a String that contains advice for the day.
When I run
netstat -an
In the command prompt of my Windows computer as suggested in one of the answers in the aforementioned link, I get a message that the port 4242 is
LISTENING
How do I close the port and make it available for future re-use?
To get rid of the LISTENING port you have to call serverSocket.close().
You have to use socket.close() after closing the writer and bufferedReader. So the Port will be free for another communication.

Asynchronous socket handling in java using the conccurent package still blocks code?

I'm trying to play around with the concurrent package and for this reason I tried to write a simple socket handler. Here is the code:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadedServer{
private final static int number_of_threads = 4;
private final static int port = 1134;
public static void main(String[] args){
try{
ServerSocket ss = new ServerSocket(port);
ExecutorService pool = Executors.newFixedThreadPool(number_of_threads);
for(;;){
pool.execute(new SocketHandler(ss.accept()));
}
}catch(Exception e){
System.out.println(e.toString());
}
}
}
class SocketHandler implements Runnable {
private Socket socket;
SocketHandler(Socket s){
this.socket = s;
System.out.println("-- Socket has connected -- ");
}
public void run(){
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = "";
while((s = reader.readLine()) != null ){
System.out.println(s);
}
}catch(Exception e){
System.out.println(e.toString());
}
}
}
This code ^^ simply waits for sockets and reads whatever the socket sends. It works fine to an extent. ( I will explain a bit later what bothers me).
The following code is the sender class which "sends" a socket
import java.io.*;
import java.net.*;
public class Sender{
public static void main(String args[]){
try{
int port = Integer.parseInt(args[0]);
Socket socket = new Socket(InetAddress.getByName(null),port);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.write("Wohoo!");
writer.close();
}catch(Exception e){
System.out.println(e.toString());
}
}
}
The code compiles fine and it even runs fine when I run my sender. However if I type
java Sender
about 3 times a second and I try to run it into my console the following thing gets printed:
java.net.BindException: Address already in use
However the whole point of this code was to not block the connections to my port and to queue the tasks. How can I tackle this?
See my comment. But I think what you are seeing is exhausting your tcp ports. Are you running this thing for awhile before it starts printing port already in use? If so read ahead.
So after closing a socket there is a state of TIME_WAIT. Until it passes, you cannot reuse same port unless you have set the socket option SO_REUSEADDR.
So you need to use that option perhaps. See this answer for more insight:
https://stackoverflow.com/a/14388707/520567

Single client to multiple client support: multithreading conversion in java

So I don't know who to go about creating a multithreaded server. I have client and server working fine together but can't introduce multiple clients properly. Here is my Server code:
package dod;
import java.net.*;
import java.io.*;
import dod.game.GameLogic;
public class Server{
Server(GameLogic game, int port) throws IOException{
ServerSocket ss = null;
Socket sock = null;
try{
ss = new ServerSocket(4444);//port no.
while(true){
try{
sock = ss.accept();
ClientThread thread = new ClientThread(game, sock);
System.out.println("Adding new player...");
thread.run();
}catch(final Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}catch(Exception d){
System.out.println(d);
}finally{
if(ss!=null){
ss.close();
}
}
}
}
Here is my thread class:
package dod;
import java.io.*;
import java.net.Socket;
import dod.game.GameLogic;
import dod.game.PlayerListener;
public class ClientThread extends CommandLineUser implements PlayerListener, Runnable{
DataInputStream in;
PrintStream out;
// The game which the command line user will operate on.
// This is private to enforce the use of "processCommand".
ClientThread(GameLogic game, Socket sock) {
super(game);
try{
in = new DataInputStream(sock.getInputStream());
out = new PrintStream(sock.getOutputStream());
}catch(IOException ioe){
System.out.println(ioe);
}
game.addPlayer(this);
}
/**
* Constantly asks the user for new commands
*/
public void run() {
System.out.println("Added new human player.");
// Keep listening forever
while(true){
try{
// Try to grab a command from the command line
final String command = in.readLine();;
// Test for EOF (ctrl-D)
if(command == null){
System.exit(0);
}
processCommand(command);
}catch(final RuntimeException e){
System.err.println(e.toString());
System.exit(1);
} catch (final IOException e) {
System.err.println(e.toString());
System.exit(1);
}
}
}
/**
* Outputs a message to the player
*
* #param message
* the message to send to the player.
*/
public void outputMessage(String message) {
out.print(message);
}
}
Not asking for new code as such, just need pointers as to what I need to do have multiple client connection at the same time! Thanks to anyone who helps out!
To start, add new Thread(clientThread) in the server and call start() on it - as is everything's happening on the same thread.
public class Server{
Server(GameLogic game, int port) throws IOException{
ServerSocket ss = null;
Socket sock = null;
try{
ss = new ServerSocket(4444);//port no.
while(true){
try{
sock = ss.accept();
ClientThread thread = new ClientThread(game, sock);
System.out.println("Adding new player...");
thread.start(); //you have to use start instead of run method to create multi thread application.
}catch(final Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}catch(Exception d){
System.out.println(d);
}finally{
if(ss!=null){
ss.close();
}
}
}
}
You have to use start instead of run method to create multi thread application.
If you want to send messages about new connections you have to hold sock in a list and when a new connection accepted send message to all socket object in list. (server broadcasts to all connected sockets)
I hope it helps.

Why is my client-server app repeating expected output?

I am having some problems figuring out this issue. I have a server that takes a string from a client, the first four characters of which act as a 'command' of sorts. rep: replaces the stored string, app: appends to it.
This works mostly fine, however when I use the rep: command, it repeats the client's string twice. So, if I inputted rep:foo the server returns 'foofoo'. I have tried analysing the code and can't see any immediate problems.
When adding some test output commands to both the server and the client, to see what the variables hold, I get the result as expected (the string input on the client minus the command characters). The code for both classes is below:
Server:
import java.io.*;
import java.net.*;
import java.util.*;
public class SynchServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
final int PORT = 1234;
Socket client;
ClientHandler2 handler; // thread for client
int clientCount = 0;
//set up server socket
try
{
serverSocket = new ServerSocket(PORT);
}
catch(IOException ioEx)
{
System.out.println("Cannot open socket!");
System.exit(1);
}
// client connections and related actions:
do
{
// wait for client...
client = serverSocket.accept();
System.out.println("Client accepted...\n");
// assign client a connection number
clientCount++;
// create thread
handler = new ClientHandler2(client, clientCount);
// run thread
handler.start();
}while(true);
}
}
class ClientHandler2 extends Thread
{
// declare thread variables
private Socket client;
private Scanner input;
private PrintWriter output;
private static String text = "";
int clientNum; // picked up from main
// constructor - set up socket and streams
public ClientHandler2(Socket socket, int clientCount)
throws IOException
{
client = socket;
clientNum = clientCount;
// streams...
// from client
input = new Scanner(client.getInputStream());
// to client
output = new PrintWriter(client.getOutputStream(), true);
}
// thread actions:
public void run()
{
String head, tail, received;
do
{
// read in line from client
received = input.nextLine();
// split input line in two - head is first four
// characters for the command, tail is for rest of
// line - the text to be manipulated:
head = received.substring(0,4);
tail = received.substring(4);
// find command and choose relevant method to execute
if(head.equals("rep:"))
{
replaceText(tail);
}
else if(head.equals("app:"));
{
appendText(tail);
}
// no further tests needed - makes server ignore
// invalid commands (Add some kind of message?)
// send modified (or not) string back to client:
output.println(clientNum + ": " + text);
}while(!received.equals("QUIT"));
// close socket connection
try
{
System.out.println("Closing connection...");
client.close();
}
catch(IOException ioEx)
{
System.out.println("Unable to close connection!");
}
}
private synchronized void replaceText(String value)
{
text = value;
}
private synchronized void appendText(String value)
{
text += value;
}
}
Client:
import java.io.*;
import java.net.*;
import java.util.*;
public class SynchClient
{
public static void main(String[] args) throws IOException
{
// declare variables
InetAddress host = null;
final int PORT = 1234;
Socket socket;
Scanner networkInput, keyboard;
PrintWriter networkOutput;
// assign host address:
try
{
host = InetAddress.getLocalHost();
}
catch(UnknownHostException uhEx)
{
System.out.println("Host ID not found!");
System.exit(1);
}
// Set up socket to server and IO streams:
socket = new Socket(host, PORT);
// from server
networkInput = new Scanner(socket.getInputStream());
// to server
networkOutput =
new PrintWriter(socket.getOutputStream(),true);
// user input
keyboard = new Scanner(System.in);
String message, response;
do
{
// get user input
System.out.print("Enter message ('QUIT' to exit): ");
message = keyboard.nextLine();
// validate user input - ensure string is >= 4 chars
// long
while(message.length() < 4)
{
System.out.print("Try again: ");
message = keyboard.nextLine();
}
// send message to server:
networkOutput.println(message);
// received response from server
response = networkInput.nextLine();
// output server response
System.out.println(response);
}while(!message.equals("QUIT"));
}
}
I really cannot figure this out, and while not vitally important, I'd like to know for reference what is going wrong. So, any hints would be nice.
Dude.
else if(head.equals("app:"));
see the semicolon at the end there? :-) Remove that, and your problems should magically go away.
edited to add: The semicolon at the end of the else block terminates the condition and the code in the brackets below is thus executed every iteration of the while loop in ClientHandler2.run()

Java - running multiple clients with eclipse

I've got codes of a server and clients written on Java. But the question is how to run multiple clients on DIFFERENT console-windows with Eclipse when server is running? Thx for helping!
(solved!!)
UPDATE**
Another question: I'll create a new question
Server:
import java.net.*;
import java.io.*;
public class ATMServer {
private static int connectionPort = 8989;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(connectionPort);
} catch (IOException e) {
System.err.println("Could not listen on port: " + connectionPort);
System.exit(1);
}
System.out.println("Bank started listening on port: " + connectionPort);
while (listening)
new ATMServerThread(serverSocket.accept()).start();
serverSocket.close();
}
}
ServerThread:
import java.io.*;
import java.net.*;
public class ATMServerThread extends Thread {
private Socket socket = null;
private BufferedReader in;
PrintWriter out;
public ATMServerThread(Socket socket) {
super("ATMServerThread");
this.socket = socket;
}
public void run(){
}
}
}
Client: (**UPDATE)
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class ATMClient {
private static int connectionPort = 8989;
public static void main(String[] args) throws IOException {
Socket ATMSocket = null;
PrintWriter out = null;
BufferedReader in = null;
String adress = "";
try {
adress = "127.0.0.1";
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Missing argument ip-adress");
System.exit(1);
}
try {
ATMSocket = new Socket(adress, connectionPort);
out = new PrintWriter(ATMSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader
(ATMSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Unknown host: " +adress);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't open connection to " + adress);
System.exit(1);
}
out.close();
in.close();
ATMSocket.close();
}
You can run as many socket clients from Eclipse provided that you pass user-defined ip/port info as command arguments from main() under Program Arguments tab in Run Configuration dialog for that program inside Eclipse rather than using some hardwired values for ip/port.
To create multiple console views (via separate Console View tabs rather than clicking on each instance), you need to create a new console view for each target instance in Eclipse Debug View mode; to achieve this, you need to select "New Console View" (from the icon button with the plus symbol to the far right of the Console View) and assign which program instance to view from each new console.
Another question: if I have to change something on ServerThread, for example, add a title, is that possible to execute that without restart the server?
Which title? I don't see any GUI code for the ServerThread code snippet. Do you mean the title name of the Console view tab?

Categories