I wrote a program which needs to connect to multiple server sockets. Each time it connects to a server, I try to save the server's InetAddress and localPort as an ArrayList in an ArrayList (connectedServers). So connectedServers is an ArrayList of ArrayLists. Before a new connection to a server is made, I try to check whether the same server is already connected with this client by checking through connectedServers.
While debugging in eclipse, the debugger stops at the line marked "ERROR" in the below code. In eclipse a new tab opens with the heading NumberFormatException(Throwable).<init>(String) line: 197 which shows the message Source not found.
If I take the marked line of code outside the if block, the connection gets made successfully. But I need it to work inside the if block. What can be the problem? The code is as follows.
public static ArrayList<ArrayList<Object>> connectedServers = new ArrayList<ArrayList<Object>>();
public static void main (String args[]) throws IOException {
listeningPort = 1111;
String host = takeInput("Host");
int port = takeInputInt("Port");
Socket a = connectToServer(host, port);
if (a != null) {
//....
}
//....
}
public static String takeInput(String inputName) throws IOException {
System.out.print(inputName+": ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
return input;
}
public static int takeInputInt(String inputName) throws IOException {
System.out.print(inputName+": ");
Scanner inputInt = new Scanner(System.in);
int input = inputInt.nextInt();
return input;
}
public static Socket connectToServer(String host, int port) throws IOException {
ArrayList<Object> element = new ArrayList<>();
element.add(host);
element.add(port);
//println(connectedServers);
//println(element);
//println(connectedServers);
if (connectedServers.contains(element) != true) {
//println(host + " " + port);
Socket fellowServer = new Socket(host, port);//<-------ERROR!!
connectedServers.add(element);
element.remove(host);
element.remove(0);
return fellowServer;
}
else{
return null;
}
}
Something could be wrong in here with input
Scanner inputInt = new Scanner(System.in);
int input = inputInt.nextInt();
Related
hi every one i have a project that get someString and intand from client and i want to send them to my server.but i have problem in getting this . i get nothing or wrong things. please help me.
Client:
//build a socket.
public void connectclient() throws IOException
{
socket = new Socket("localhost", 9097);
System.out.println("connect to server on port 9097");
}
public void startstreams() throws IOException , ClassNotFoundException
{
in = socket.getInputStream();
out = socket.getOutputStream();
dos = new DataOutputStream(out);
dis = new DataInputStream(in);
writer = new OutputStreamWriter(out);
reader = new InputStreamReader(in);
breader = new BufferedReader(reader);
bwriter = new BufferedWriter (writer);
w = new PrintWriter(out, true);
}
public void writeSocketMyJson(String n) throws IOException
{
w = new PrintWriter(out, true);
w.println(n);
w.flush();
w.close();
}
massage1 = "username";
//send username that get from login form to server.
public void sendusername() throws IOException
{
writeSocketMyJson(massage1);
}
massage2 ="admin";
//send password that get from login form to server.
public void sendpassword() throws IOException
{
writeSocketMyJson(massage2);
}
//send access level to server.
public void sendaccess(int l) throws IOException
{
dos.writeInt(l);
dos.flush();
}
sendaccess(21);
Server:
//build server.
public void connectserver() throws IOException
{
listener = new ServerSocket(9097);
System.out.println("Server is running on port 9097 ...");
}
//wait for new connection.
public void waitforclient() throws IOException
{
socket = listener.accept();
System.out.println("A new client connected to the server");
}
public void startstreams() throws IOException
{
in = socket.getInputStream();
out = socket.getOutputStream();
dos = new DataOutputStream(out);
dis = new DataInputStream(in);
writer = new OutputStreamWriter(out);
reader = new InputStreamReader(in);
bwriter = new BufferedWriter (writer);
breader = new BufferedReader (reader);
}
public String readSocket() throws IOException
{
breader = new BufferedReader(reader);
while (true)
{
massage = new String();
massage = breader.readLine();
if (massage.equals(null) == false)
{
break;
}
}
return(massage);
}
//get username that client send it.
public String getusername() throws IOException, ClassNotFoundException
{
try
{
username = new String();
username = readSocket();
System.out.println("the username is : " + username);
}
catch(IOException IOE)
{
IOE.printStackTrace();//if there is an error, print it out
}
return(username);
}
//get password that client send it.
public String getpassword() throws IOException, ClassNotFoundException
{
try
{
password = new String();
password = readSocket();
System.out.println("the password is : " + password);
}
catch(IOException IOE)
{
IOE.printStackTrace();//if there is an error, print it out
}
return(password);
}
//get commend from client.
//admin or user send which commend 21-add new information 22-show information
public int getaccess() throws IOException
{
System.out.println("server get access : " + dis.readInt());
return(dis.readInt());
}
but when i call getpassword()i get nothing .
when i callgetaccess()i get nothing.
why? please help me.
i have main class too that control the orders
main:
//build Server & Client
Server server = new Server();
Client client = new Client();
//Start Server & Client
server.connectserver();
client.connectclient();
//Server wait for new connection
server.waitforclient();
//start the Streams
server.startstreams();
client.startstreams();
client.sendusername();
String msg1 =server.readSocket();
client.sendpassword();
String msg2 =server.readSocket();
client.sendaccess();
int n = getaccess();
Your code is full of nonsense. You do things like
breader = new BufferedReader (reader);
public String readSocket() throws IOException
{
breader = new BufferedReader(reader);
and like
w = new PrintWriter(out, true);
public void writeSocketMyJson(String n) throws IOException
{
w = new PrintWriter(out, true);
and like
password = new String();
password = readSocket();
I would suggest that you just throw it all away and begin from scratch, with some sample code for java sockets, of which there exist numerous on the interwebz.
The thing to remember is that you cannot just pretend that a socket is a regular stream, and you cannot just create a BufferedReader on top of it. At any given moment you need to know exactly how many bytes were sent, and therefore exactly how many bytes to expect to receive.
So generally, on the sending side you cannot write a string and expect on the receiving side the end of the string to be detected with an end-of-line. On the sending side you need to first write the length of the string, as a 32-bit int, so on the receiving side you know you are expecting exactly 4 bytes that contain the length of the string that follows. Then, you can read the exact right number of bytes that make up the string. Of course, do not forget that in java, a character is 2 bytes long.
I am trying to create a text messaging program with three files (main function file, client file, server file) where text messages can be sent and received at the same time, multiple times (ability to send multiple messages by pressing enter after each message, ability to receive multiple messages after connection after the other side presses enter after each message)
There are four threads (one thread for receiving messages on server, one thread for sending messages on server, one thread for receiving messages on client, one thread for sending messages on client)
If "-l" is present on the command line, it will run as a server, otherwise it will run as a client
Command line arguments to run server:
java DirectMessengerCombined -l 3000
Command line arguments to run client:
java DirectMessengerCombined 3000
The command line arguments (String[] args) should be accessible to all 3 files.
Here is the code where the threads are created:
Code of main function file:
import java.io.IOException;
public class DirectMessengerCombined implements Runnable
{
public static void main(String[] args) throws IOException
{
DirectMessengerClient client1 = null;
DirectMessengerServer server1 = null;
Thread ServerRead = new Thread ();
Thread ServerWrite = new Thread ();
Thread ClientRead = new Thread ();
Thread ClientWrite = new Thread ();
for (int i = 0; i < args.length; i++)
{
if (args.length == 1)
{
client1 = new DirectMessengerClient(args);
client1.ClientRun(args);
ClientRead.start();
ClientWrite.start();
}
else if (args.length == 2)
{
server1 = new DirectMessengerServer(args);
server1.ServerRun(args);
ServerRead.start();
ServerWrite.start();
}
i=args.length + 20;
}
}
#Override
public void run()
{
//This method is just to get rid of the "implements" error
//There are four threads, so which one is accessing this method??
}
}
In the following code there are comments such as "//I would like this to be the ServerRead thread method". I would like to know how to make that comment viable or put it into real code somehow to make it work with the corresponding threads in the main function file
Code of Server file:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
public class DirectMessengerServer implements Runnable
{
private String[] serverArgs;
private static Socket socket;
public boolean keepRunning = true;
int ConnectOnce = 0;
public DirectMessengerServer(String[] args) throws IOException
{
// set the instance variable
this.serverArgs = args;
run();
}
public String[] ServerRun(String[] args) throws IOException
{
serverArgs = args;
serverArgs = Arrays.copyOf(args, args.length);
return serverArgs;
}
//I would like this to be the ServerRead thread method
public void run()
{
try
{
if(ConnectOnce == 0)
{
int port_number1 = Integer.valueOf(serverArgs[1]);
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
ConnectOnce = 4;
}
while(keepRunning)
{
//Reading the message from the client
//BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromClient = br.readLine();
System.out.println("Message received from client: "+ MessageFromClient);
// ServerSend.start();
runSend();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
//I would like this to be the ServerWrite thread method
public void runSend()
{
while(keepRunning)
{
System.out.println("Server sending thread is now running");
try
{
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(
new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
ConnectOnce = 4;
// run();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
}
}
}
}
Client file code:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class DirectMessengerClient
{
private String[] clientArgs;
private static Socket socket;
public boolean keepRunning = true;
public DirectMessengerClient(String[] args) throws IOException
{
// set the instance variable
this.clientArgs = args;
run(args);
}
public String[] ClientRun(String[] args)
{
clientArgs = args;
clientArgs = Arrays.copyOf(args, args.length);
return clientArgs;
}
//I would like this to be the ServerWrite thread method
public void run(String args[]) throws IOException
{
System.out.println("Client send thread is now running");
while(keepRunning)
{
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
int port = Integer.valueOf(port_number1);
String host = "localhost";
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input
BufferedReader input= new BufferedReader(new InputStreamReader(System.in));
String line = "";
line= input.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
runClientRead(args);
}
}
//I would like this to be the ClientRead thread method
public void runClientRead(String args[]) throws IOException
{
System.out.println("Client recieve/read thread is now running");
//Integer port= Integer.valueOf(args[0]);
//String host = "localhost";
//InetAddress address = InetAddress.getByName(host);
//socket = new Socket(address, port);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String MessageFromServer = br.readLine();
System.out.println("Message received from server: " + MessageFromServer);
}
}
My question is how to make those methods work with the threads inside the main function file and/or how to turn the comments into real code for the corresponding threads in the main file?
EDIT: I am able to get it to send one message at a time successfully now, is there a way to make it so I can send and receive multiple messages at a time?
I'm using sockets to chat as part of a large application, however so you can read it easier i have made 2 classes that show the problem. I have a server and a client, the server opens a socket and waits for a client to connect once connected it sends them a welcome message. On the client side they display the welcome message then enter a loop to write to the PrintWriter. On the server side it will now enter a loop that constantly displays text from the bufferedReader however nothing is printing out, not sure if i'm being stupid but think it needs a fresh pair of eyes, Thanks.
public class Server {
public static boolean running = true;
public static PrintWriter out;
public static BufferedReader in;
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(1932);
while (true) {
Socket cs = s.accept();
out = new PrintWriter(cs.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cs.getInputStream()));
out.println("Welcome");
out.flush();
while (running == true) {
String input = in.readLine();
if (input.equals("QUIT")) {
System.out.println("theyve gone :( ");
cs.close();
running = false;
} else {
System.out.println(input);
}
}
}
}
}
public class Client {
public static boolean running = true;
public static PrintWriter out;
public static BufferedReader in;
public static Scanner scan;
public static void main (String [] args) throws IOException{
Socket so = new Socket("localhost", 1932);
out = new PrintWriter(so.getOutputStream());
in = new BufferedReader(new InputStreamReader(so.getInputStream()));
System.out.println("TYPE QUIT TO LEAVE ");
System.out.println(in.readLine());
while(true){
scan = new Scanner(System.in);
String message = scan.next();
out.print(message);
out.flush();
}
}
}
In the server, you're reading the next line:
String input = in.readLine();
So the server blocks until the end of line is reached (or the stream is closed).
And on the client, you never send any end of line:
out.print(message);
I have a very simple capitalization Java program. Client sends text read from standard input to server which converts that text into capital letters. Program works well but once client is stopped (NetBeans ide used), server is also reset. Server socket should keep listening for new connection from clients regardless of a client being stopped.
public class Client
{
public static void main(String[] args) throws IOException
{
try(Socket s=new Socket("localhost",9090))
{
while(true)
{
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
BufferedReader rd=new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedReader from=new BufferedReader(new InputStreamReader(System.in));
String read=from.readLine();
out.println(read);
String answer;
answer=rd.readLine();
System.out.println(answer);
}
}
}
}
public class Server
{
public static void main(String[] args) throws IOException
{
try(ServerSocket listener = new ServerSocket(9090);
Socket socket = listener.accept();)
{
while (true)
{
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Started...");
String transform=br.readLine();
String newStr=transform.toUpperCase();
out.println(newStr);
}
}
}
}
What happens is a normal behaviour. You server code only includes handling of a single client. The listener.accept() function only accepts latest connection to server. You need to put the listened.accept() in loop and handle all the exceptions that are raised within. The server-side code should look like this:
public class Server
{
public static void main(String[] args) throws IOException
{
try(ServerSocket listener = new ServerSocket(9090);
while (true) {
try {
Socket socket = listener.accept();)
…
} catch (SocketException ex) {
...
}
}
}
}
But keep in mind that this code will only handle single client at a time. No multi-threading in this code.
Your Server is closing the connection and then finishing becuase it is created outside the while loop. I believe this is what you need.
public class Server {
public static void main (final String[] args)
throws IOException {
while (true) {
try (ServerSocket listener = new ServerSocket(9090); Socket socket = listener.accept();) {
while (true) {
final BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
final PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Started...");
final String transform = br.readLine();
if (transform == null)
break;
final String newStr = transform.toUpperCase();
out.println(newStr);
}
}
}
}
}
Here is my Server class, along with Admin/Client... The admin can recieve the initial message from the server, but cannot respond back to the server. The Server Socket is created, and when the admin connects to the Server, The Server's message is recieved and printed. Although once the Server's menu printout("1. Login, etc..."). I cannot enter an option via the console. It seems to be in a deadlock as soon as the admin prints out the menu sent from the server.
/**
A server that executes the Simple Bank Access Protocol.
*/
public class BankServer extends Thread {
private Socket sAdmin;
private Scanner inServer;
private PrintWriter outServer;
public static void main(String[] args) throws IOException {
Bank bank = new Bank(10);
ServerSocket server = new ServerSocket(8888);
System.out.println("Waiting for clients to connect...");
Thread admin = new BankServer();
admin.start();
while (true) {
Socket s = server.accept();
System.out.println("Client connected.");
BankService service = new BankService(s, bank);
Thread t = new Thread(service);
t.start();
}
}
#SuppressWarnings("resource")
public void run() {
try {
ServerSocket server = new ServerSocket(8889);
try {
System.out.println("Waiting for admin to connect...");
while (true) {
sAdmin = server.accept();
System.out.println("Admin connected.");
InputStream instream = sAdmin.getInputStream();
OutputStream outstream = sAdmin.getOutputStream();
inServer = new Scanner(instream);
outServer = new PrintWriter(outstream);
outServer.print(...+"1. Login\n"+etc...);
outServer.flush();
findCommand();
}
} finally {
sAdmin.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void findCommand() throws IOException {
while (true) {
if (!inServer.hasNext()) {
return;
}
String command = inServer.next();
String chosenCommand;
switch (command) {
case "1":
chosenCommand = "LOGIN";
runCommand(chosenCommand);
break;
case "2":
etc...
}
}
}
...
}
Ive removed the runCommand method and some fields that don't cause problems to allow for an easier read.
Here is the the admin class. It will output the options sent from the server, but will not exit the loop of outputing the intial message, and allow me to enter a choice.
public class BankAdmin {
public static void main(String[] args) throws IOException {
Socket inAdmin = new Socket("localhost", 8889);
InputStream instream = inAdmin.getInputStream();
OutputStream outstream = inAdmin.getOutputStream();
Scanner in = new Scanner(instream);
PrintWriter adminOut = new PrintWriter(outstream);
Scanner console = new Scanner(System.in);
while (true) {
if (!in.hasNextLine()) {
String command = console.next();
System.out.println("Sending: " + command);
adminOut.print("command");
adminOut.flush();
} else {
String response = in.nextLine();
System.out.println(response);
}
}
}
}
This is what is happening:
After the server sends the menu to the client, the client becomes stuck in in.hasNextLine(). This is because the in.hasNextLine() will block (pause) for input, waiting for a new line (otherwise, it cannot determine whether there will be a next line). To fix this problem, you must use threads, with one waiting for input while the other reads from the console.
For more information, see the Javadoc on Scanner.hasNextLine()