I have a JavaFX app which reads the input of a number and then sends it to a server. The server calculates the sum of its digits and then gives the result back to the app. Im using the Task class in order to not alter the main thread of the application.
Part of the code of the app
calculate.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Task<String> task = new Task<String>() {
String result_from_server;
#Override
protected String call() throws Exception {
try(Socket socket = new Socket("localhost",PORT);
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
warning.setText("");
result.setText("");
if(!input.getText().equalsIgnoreCase("")){
out.print(input.getText());
result_from_server = in.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
return result_from_server;
}
};
task.setOnSucceeded(event1 -> {
result.setText(task.getValue());
});
new Thread(task).start();
}
});
The server
public class QuersummeServer{
static final int PORT = 4444;
public static void main(String[] args){
try(ServerSocket ss = new ServerSocket(PORT);
Socket cs = ss.accept();
PrintWriter out = new PrintWriter(cs.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(cs.getInputStream()))){
String number = in.readLine();
int result = calculate(number);
out.print(result);
}catch (IOException e){
e.printStackTrace();
}
}
private static int calculate(String number) {
int result = 0;
for(int i = 0;i<number.length();i++){
result+= Integer.valueOf(number.substring(i,i+1));
}
return result;
}}
At the end nothing happens, what is wrong?
Thanks in advance
Edit: I figured out that the server blocks after in.readLine() but I dont know why
Try in the client class after out.print(input.getText()); to call out.flush()
Related
I'm trying to build a server with Java.
My question is: how to do if I have multiple users at the same time? The answer is: multi threading. But I don't know how to do.
For example, if there is two client connected at the same time, and a server (who does 2*number) : if the client1 say "50" to the server and the client 2 "10", the server is supposed to return "100" to the first client and "20" to the second. But i'm not sure my code works.
Server side:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
socket = new ServerSocket(4444);
Thread t = new Thread(new Accept(socket));
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private ServerSocket socketserver;
private Socket socket;
private int nbrclient = 1;
public Accept(ServerSocket s){
socketserver = s;
}
public void run() {
try {
socket = socketserver.accept();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
out = new PrintWriter(socket.getOutputStream());
out.println("Pong");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client side:
public class Client {
public static void main(String[] zero) {
Socket socket;
BufferedReader in;
PrintWriter out;
try {
socket = new Socket(InetAddress.getLocalHost(),4444);
out = new PrintWriter(socket.getOutputStream());
out.println("Ping");
out.flush();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
socket.close();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
If you have any ideas (how to do multi-threading and how to verify if my code works, like run two Clients.java and check if the multi-threading works)
The Server sides needs a while loop:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
while(true){
socket = new ServerSocket(4444);
Socket socketInstance = socket.accept();
Thread t = new Thread(new Accept(socketInstance));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private Socket socket;
private int nbrclient = 1;
public Accept(Socket s){
socket = s;
}
public void run() {
try {
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);//this message should be your number
Double number = Double.parseString(message);
out = new PrintWriter(socket.getOutputStream());
//out.println("Pong");
out.println(2*number +"");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client side looks ok. Just replace out.println("Ping"); with out.println("50"); or whatever you want.
You first start the server and then you can start multiple client applications. If you have any errors you can then post them here and have a look on an exact scenario.
This question already has answers here:
Java Socket why server can not reply client
(4 answers)
Closed 3 years ago.
My android app is supposed to send data to the server through socket but also occasionally receive data from that server. To do that I am using service and.
Sending data to the server works ok, I'm using service method that i'm calling from activity. But while sending works just fine my app doesnt receive any data back. While I send string "pp" I should get another sring back from server but that just doesn't happen. What am I doing wrong?
My service:
public class MyService extends Service {
private Socket socket;
public static PrintWriter out;
private BufferedReader in;
private String line;
private final IBinder binder = new MyBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder {
MyService getMyService() {
return MyService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("10.0.2.2");
socket = new Socket(serverAddr,8998);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Thread thread = new Thread(new Listener());
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
return START_STICKY;
}
private class Listener implements Runnable{
#Override
public void run() {
while(true){
try {
line = in.readLine();
if(line!=null) Log.d(line,line); //never shows up in logcat
line=null;
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void send(String line){
out.println(line);
}
}
And my server:
public class Server {
private static final int SERVER_PORT = 8998;
private static ServerSocket server = null;
private static Socket client = null;
private static BufferedReader in = null;
private static boolean isConnected = true;
private static String line;
public static void main(String[] args){
while(isConnected){
if(server==null || server.isClosed()){
try{
server = new ServerSocket(SERVER_PORT);
client = server.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Connected");
}catch (IOException e){
System.out.println("Error in opening Socket"+e);
System.exit(-1);
}
}
else{
try{
line = in.readLine();
if(line != null)
{
if(line.equals("pp")){
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(client.getOutputStream())),
true);
String toSend = "String to send";
out.write(toSend);
System.out.println("sent");
}
System.out.println(line);
}else if(in.read()==-1){
client.close();
server.close();
}
}catch (IOException e){
System.out.println("Read from client failed");
System.exit(-1);
}
}
}
}
}
Usual problems.
You are reading lines but you aren't writing lives. Add a line terminator.
You should stop reading when readLine() returns null, and close the socket.
Once readLine() has returned null, the extra read test is pointless. It will always return -1.
I've got a working simple client-server app. The problem is it works fine just with one started client, but not with two or more. It establish connection, but when you try to enter text in first or second, the server breakes. I think that problem may be at the function broadcast() in Server.java.
Server.java
public class Server {
final int PORT = 5000;
private ArrayList<NewClient> al = new ArrayList<NewClient>();
private Scanner in;
private PrintWriter out;
private SimpleDateFormat sdf;
private int uniqueID = 0;
private void go(){
try{
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Waiting for clients...");
while(true) {
Socket s = serverSocket.accept();
NewClient chat = new NewClient(s);
System.out.println("Client number " + chat.getId() + " connected from: " + s.getLocalAddress().getHostName());
al.add(chat);
Thread t = new Thread(chat);
t.start();
}
}catch (Exception e) {
System.out.println("Problem with establishing network connection: ");
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.go();
}
class NewClient implements Runnable{
private Socket socket;
private int id;
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
}
public int getId() {
return this.id;
}
#Override
public void run() {
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
while(true) {
String input = in.nextLine();
System.out.println("Client said: " + input);
broadcast(input);
}
}catch (Exception e) {
e.printStackTrace();
}
}
private void writeMsg(String input) {
String msg = input + " on " + sdf.format(new Date());
out.println("You said: " + msg);
out.flush();
}
private void broadcast(String input) {
for (int i = 0; i < al.size(); i++) {
NewClient t = al.get(i);
t.writeMsg(input);
}
}
}
}
Client.java:
public class Client {
final int PORT = 5000;
final String HOST = "127.0.0.1";
private Scanner stdIn;
private Scanner in;
private PrintWriter out;
private void go() {
setUpNetwork();
}
private void setUpNetwork(){
try{
Socket s = new Socket(HOST, PORT);
System.out.println("You are connected to " + HOST);
NewClient client = new NewClient(s);
Thread t = new Thread(client);
t.start();
} catch (Exception e) {
System.out.println("Problem with connection to server: " + e);
}
}
public static void main(String[] args) {
Client client = new Client();
client.go();
}
class NewClient implements Runnable {
private Socket socket;
public NewClient(Socket s) {
this.socket = s;
}
#Override
public void run() {
try {
stdIn = new Scanner(System.in);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.print("> ");
String input = stdIn.nextLine();
out.println(input);
out.flush();
if(in.hasNext()) {
System.out.println(in.nextLine());
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
When opens two Client.java and connect it to the server.java everything is ok. But when i try to send some message from this two opened clients server returns these errors:
java.lang.IndexOutOfBoundsException: end
at java.util.regex.Matcher.region(Matcher.java:1038)
at java.util.Scanner.findPatternInBuffer(Scanner.java:1010)
Client said: sds
at java.util.Scanner.findWithinHorizon(Scanner.java:1679)
at java.util.Scanner.nextLine(Scanner.java:1538)
at Server$NewClient.run(Server.java:66)
at java.lang.Thread.run(Thread.java:745)
What's happening is that your code scans the first line from the client ("sds", which is printed to stdout), and then it loops back and immediately tries to scan the next line from the client. Since the client hasn't sent anything more yet, the input stream scanner throws an exception.
The NewClient class is an inner class. All instances of this class are created with the same instance of the outer class. Changing the code will sove the problem:
public NewClient(Socket s) {
this.socket = s;
this.id = ++uniqueID;
try{
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
sdf = new SimpleDateFormat("HH:mm:ss");
}catch(Exception e) {
System.out.println("Exception while creating input/output streams: " + e);
}
}
I have a simple Server-Multi Client program that sends input from a user out to everyone.
The Server gets messages, and then sends them systematically out to everyone.
The problem I'm having is that the server gets the messages, but doesn't send them back until I disconnect from the server. I have one thread for each user, and one thread that sends out the messages.
Here is the Main server:
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(25566);
SendThread SendThread = new SendThread();
new Thread(SendThread).start();
while(true){
Socket clientSocket = serverSocket.accept();
CollectThreads socketThread = new CollectThreads(clientSocket);
SendThread.Clients.add(socketThread);
new Thread(socketThread).start();
}
}
Here is the Input Thread(CollectThreads):
public Socket Client;
public CollectThreads(Socket socket)
{
//Here we set the socket to a local variable so we can use it later
Client = socket;
}
#Override
public void run() {
System.out.println("i");
try{
PrintWriter out = new PrintWriter(Client.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(Client.getInputStream()));
out.println("Connected");
boolean x = true;
while(x){
String s;
if((s = in.readLine()) != null){
System.out.println(s);
SendThread.log.add(s);
}
}
} catch(IOException exception) {
System.out.println("Error: " + exception);
}
}
And the Sender(SendThread):
public ArrayList<CollectThreads> Clients = new ArrayList<CollectThreads>();
public static ArrayList<String> log = new ArrayList<String>();
#Override
public void run() {
try{
while(true){
String x;
while(!Clients.isEmpty()){
x = log.get(0);
for(int c = 0; c < Clients.size(); c += 1){
PrintWriter out = new PrintWriter(Clients.get(c).Client.getOutputStream(), true);
out.println(x);
System.out.println(x);
}
log.remove(0);
}
}
} catch(IOException exception) {
System.out.println("Error: " + exception);
}
}
If I input x, The server console prints x, I disconnect, and then it prints x the second time.
Can anyone find my mistake? or tell me why this isn't working?
You're never removing anything from SendThread.Clients, so I can't see why it won't just keep resending the same thing indefinitely.
It's a very strange design. Why not have each client thread send its own output, like everybody else?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am making a simple Web Server where I spawn a new thread each time a client connects. I then need to send a response using a BufferedOutputStream(since the HTTP protocol requires a /r/n at the end of the line).
Here is my code:
class HttpServer{
public static void main(String args[]){
ServerSocket ss = null;
int port = 40000;
try{
if(args.length > 0){
port = Integer.parseInt(args[0]);
}
ss = new ServerSocket(port);
while(true){
Socket client = ss.accept();
User user = new User(client);
user.start();
}
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
}
And my User class:
class User extends Thread{
Socket client;
public User(Socket s){
client = s;
}
public void run(){
try{
BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
println(bos, "Hello World");
bos.close();
client.close();
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
private void println(BufferedOutputStream bos, String s) throws IOException {
String news = s + "\r\n";
byte[] array = news.getBytes();
for(int i=0; i<array.length; i++){
bos.write(array[i]);
}
return;
}
}
The problem occurs when I try and create the BufferedOutputStream; it gives me a "Socket is closed" error and I have no idea why.
Any help would be much appreciated.
Thanks!
This is the code that doesn't work:
class User extends Thread{
Socket client;
public User(Socket s){
client = s;
}
public void run(){
try{
System.out.println("Address: " + client.getInetAddress().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line;
Boolean first = true;
while(!((line = reader.readLine()).equals(""))){
if(first)
System.out.println(line.split(" ")[1]);
first = false;
}
reader.close();
BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
println(bos, "Hello World");
bos.close();
// Close socket
client.close();
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
private void println(BufferedOutputStream bos, String s) throws IOException {
String news = s + "\r\n";
byte[] array = news.getBytes();
for(int i=0; i<array.length; i++){
bos.write(array[i]);
}
return;
}
}
This exception means that you closed the Socket.
Closing the input stream or the output stream of a socket closes the other two, and closing any FilterInput/OutputStream/Reader/Writer closes the stream/reader/writer it is filtering.
So far as I can tell, there is no problem with your code. It seems more likely that the operating system or browser is restricting access to your server in some way.
Socket client = ss.accept();
User user = new User(client);
user.start();
The accept call blocks waiting for connections. Your User thread is never created. You should create a new User class which creates a new thread for you and writes your messages to the server.
public class User extends Thread{
Socket client;
int port;
public User(int p) throws UnknownHostException, IOException{
port = p;
client = new Socket(InetAddress.getLocalHost(), 40000);
}
public void run(){
try{
BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream());
println(bos, "Hello World");
bos.close();
client.close();
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
private void println(BufferedOutputStream bos, String s) throws IOException {
String news = s + "\r\n";
byte[] array = news.getBytes();
for(int i=0; i<array.length; i++){
bos.write(array[i]);
}
return;
}
public static void main(String[] args) throws UnknownHostException, IOException {
User user = new User(4000);
user.start();
}
}
The server should only listen to incoming connections.(and perhaps print it)
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
class HttpServer{
public static void main(String args[]){
ServerSocket ss = null;
int port = 40000;
try{
if(args.length > 0){
port = Integer.parseInt(args[0]);
}
ss = new ServerSocket(port);
while(true){
Socket client = ss.accept();
Scanner scanner = new Scanner(client.getInputStream());
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}
}
catch(Exception e){
System.err.println(e.getMessage());
}
}
}
Run both of them as different java processes and you should see hello world at server side.
If you change your port you may have to change this on the client side too.