I've got a client and server coded in Java, once the server has received one message from the client, the server stops receiving all new messages. No errors are thrown when the client tries to sent more messages. I can't seem to find out why it doesn't allow or receive new connections! Please help.
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
boolean Listening = true;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
}
catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (Listening){
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
//os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the client.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
while (true)
{
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
after accepting a connection it is entering into this infinite loop.due to this loop it will never accept new connection.
to solve this issues, start new thread each time when new client comes, pass socket connection of the client and read data from that client.
I see two issues as below:
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
Here you need to break after reading the content from the Socket irrespective of whether you read in different thread or same.
You need to declare boolean Listening to volatile else the server wont stop.
while (true) {
line = is.readLine();
if(line != null){
//os.println(line);
log(Level.SEVERE, "New connection to server {0}", line);
}
}
the code will block new request, so the second request will not be accepted.
I make an example accounding to your code. Hope it help to you.
The Server Class will only be userd to accept socket connection and create a new thread to process it.
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server implements Runnable {
#Override
public void run() {
ServerSocket echoServer = null;
boolean listening = true;
Socket clientSocket = null;
int sPort = 9999;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(sPort);
} catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
while (listening) {
try {
clientSocket = echoServer.accept();
System.out.println("receive new connection");
new ProcessClientThread(clientSocket).start();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
}
The ProcessClientThread Class extends Thread Class and defined a constructor with a Socket type parameter. Override run method of it. The run method get input stream from socket and print it out. When it accept 0, it will close the scoket connection. Its code like this
import java.io.DataInputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
public class ProcessClientThread extends Thread {
Socket socket = null;
public ProcessClientThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
DataInputStream is;
String line;
boolean flag = true;
try {
is = new DataInputStream(socket.getInputStream());
while (flag) {
line = is.readLine();
if (Integer.valueOf(line) != 0) {
// os.println(line);
// Logger.getLogger(Level.SEVERE,
// "New connection to server {0}", line);
System.out.println(line);
} else {
Writer w = new OutputStreamWriter(socket.getOutputStream());
w.write(0);
w.flush();
flag = false;
socket.close();
System.out.println("close a connection");
}
}
} catch(Exception e) {
}
}
}
There is a StartUp Class which used to start up the server thread.
public class StartUp {
public static void main(String[] args) {
new Thread(new Server()).start();
}
}
Run the below Client Class to test the Server.
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 9999);
OutputStreamWriter writer = new OutputStreamWriter(client.getOutputStream());
Reader reader = new InputStreamReader(System.in);
Reader serverReader = new InputStreamReader(client.getInputStream());
boolean flag = true;
while(flag) {
int readContent = reader.read();
writer.write(readContent);
writer.flush();
if(readContent == 0) {
writer.close();
client.close();
flag = false;
}
}
}
}
Related
I want to send arraylist on multithreading server to client . So far i just write the conection and the clients can write and send to server msg ,the server just send back the msg to client is write somathing just sending. My main problems is how to transfer from server to client the arraylist ?
i am new on this and i dont know nothing for arralist .
code server :
import java.io.*;
import java.net.*;
import java.util.ArrayList;
// Server class
class Server {
public static void main(String[] args)
{
private ArrayList<Objects> Obj = new ArrayList<Objects>();
// file read
// String filePath = "Hotels_new.txt";
// System.out.println(Read_File( filePath ));
ServerSocket server = null;
try {
// server is listening on port 1234
server = new ServerSocket(1234);
server.setReuseAddress(true);
// running infinite loop for getting
// client request
while (true) {
// socket object to receive incoming client
// requests
Socket client = server.accept();
// Displaying that new client is connected
// to server
System.out.println("New client connected" + client.getInetAddress().getHostAddress());
// create a new thread object
ClientHandler clientSock = new ClientHandler(client);
// This thread will handle the client
// separately
new Thread(clientSock).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static String Read_File(String filePath)
{
// Declaring object of StringBuilder class
StringBuilder builder = new StringBuilder();
// try block to check for exceptions where
// object of BufferedReader class us created
// to read filepath
try (BufferedReader buffer = new BufferedReader(
new FileReader(filePath))) {
String str;
// Condition check via buffer.readLine() method
// holding true upto that the while loop runs
while ((str = buffer.readLine()) != null) {
builder.append(str).append("\n");
}
}
// Catch block to handle the exceptions
catch (IOException e) {
// Print the line number here exception occurred
// using printStackTrace() method
e.printStackTrace();
}
// Returning a string
return builder.toString();
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
// Constructor
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
// get the outputstream of client
out = new PrintWriter( clientSocket.getOutputStream(), true);
// get the inputstream of client
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
// writing the received message from
// client
System.out.printf(" Sent from the client: %s\n",line);
out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (out != null) {
out.close();
}
if (in != null)
{
in.close();
clientSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
code client:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.ArrayList;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
// establish a connection by providing host and port
// number
try (Socket socket = new Socket("localhost", 1234)) {
// writing to server
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
// reading from server
BufferedReader in
= new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// object of scanner class
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
// reading from user
line = sc.nextLine();
// sending the user input to server
out.println(line);
out.flush();
// displaying server reply
System.out.println("Server replied "
+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
In order to send something more complex you will have to serialize it. You can choose how to do the serialization, maybe the easiest is to use ObjectOutputStream and ObjectInputStream on the server and client respectively. These can be used very similarly to the PrintWriter / BufferedReader solution you are doing now.
I had to change a few things as your example code did not compile.
Example server based on your code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class Server {
private static final List<Integer> myIntArray = List.of(1, 2, 3);
public static void main(String[] args) {
ServerSocket server = null;
try {
// server is listening on port 1234
server = new ServerSocket(1234);
server.setReuseAddress(true);
// running infinite loop for getting
// client request
while (true) {
// socket object to receive incoming client
// requests
Socket client = server.accept();
// Displaying that new client is connected
// to server
System.out.println("New client connected" + client.getInetAddress().getHostAddress());
// create a new thread object
ClientHandler clientSock = new ClientHandler(client);
// This thread will handle the client
// separately
new Thread(clientSock).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
// Constructor
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(clientSocket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
while (in.readLine() != null) {
objectOutputStream.writeObject(myIntArray);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Example client:
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args) {
// establish a connection by providing host and port
// number
try (Socket socket = new Socket("localhost", 1234);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
// object of scanner class
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
// reading from user
line = sc.nextLine();
// sending the user input to server
out.println(line);
out.flush();
// displaying server reply
List<Integer> integers = (List<Integer>) ois.readObject();
System.out.println("server: " + integers.get(0));
}
// closing the scanner object
sc.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Keep in mind that if you are about to send your own custom types, both sides will have to know about those to be able to serialize/deserialize. Also, your classes will have to be serializable.
I am trying to make a Server Client program that allows sending multiple messages from server to client or vice versa without waiting for a response. The program works fine when the first client is connected and disconnected. But when I connect the client again, I get the error. Here is my server code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
class Q2Server implements Runnable{
private ServerSocket serverSocket;
private Socket socket;
private DataOutputStream out;
private BufferedReader in1;
private DataInputStream in2;
private Thread read, write;
private String clientMsg, serverMsg;
public Q2Server (int port) throws IOException{
serverSocket = new ServerSocket(port);
while(true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
socket = serverSocket.accept();
System.out.println("Just connected to " + socket.getRemoteSocketAddress());
out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Thanks for connecting to " + socket.getLocalSocketAddress());
clientMsg = "";
serverMsg = "";
read = new Thread(this);
write = new Thread(this);
read.start();
write.start();
read.join();
write.join();
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
public void run () {
try {
if(Thread.currentThread() == write) {
while(true) {
try {
if(clientMsg.equals("close")) {
break;
} else {
in1 = new BufferedReader(new InputStreamReader(System.in));
out = new DataOutputStream(socket.getOutputStream());
serverMsg = in1.readLine();
out.writeUTF(serverMsg);
if(serverMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
}
} catch (SocketException s) {
break;
}
}
} else {
while(true) {
try {
if(serverMsg.equals("close")) {
break;
}
in2 = new DataInputStream(socket.getInputStream());
clientMsg = in2.readUTF();
System.out.println("Client: " + clientMsg);
if(clientMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch(SocketException s) {
break;
}
}
}
} catch (IOException i) {
i.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Q2Server server = new Q2Server(8080);
}
}
Client code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.rmi.UnexpectedException;
import java.io.InputStreamReader;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.lang.Thread;
class Q2Client implements Runnable {
private Socket socket;
private Thread read, write;
private BufferedReader in1;
private DataInputStream in2;
private DataOutputStream out;
private String clientMsg, serverMsg;
public Q2Client(int port) {
try {
socket = new Socket("localHost",port);
System.out.println("Connected to port: " + port);
clientMsg = serverMsg = "";
read = new Thread(this);
write = new Thread(this);
in2 = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
System.out.println(in2.readUTF());
read.start();
write.start();
read.join();
write.join();
} catch(UnexpectedException u) {
u.printStackTrace();
} catch(IOException i) {
i.printStackTrace();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
public void run() {
try {
if(Thread.currentThread() == write) {
while(true) {
try {
if(serverMsg.equals("close")) {
break;
}
in1 = new BufferedReader(new InputStreamReader(System.in));
out = new DataOutputStream(socket.getOutputStream());
clientMsg = in1.readLine();
out.writeUTF(clientMsg);
if(clientMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch (SocketException s) {
break;
}
}
} else {
while(true) {
try {
if(clientMsg.equals("close")) {
break;
}
in2 = new DataInputStream(socket.getInputStream());
serverMsg = in2.readUTF();
System.out.println("Server: " + serverMsg);
if(serverMsg.equals("close")) {
socket.close();
in1.close();
in2.close();
out.close();
System.out.println("Closing connection...");
break;
}
} catch (SocketException s) {
break;
}
}
}
} catch (IOException i) {
i.printStackTrace();
}
}
public static void main(String[] args) {
Q2Client client = new Q2Client(8080);
}
}
Here is the stacktrace of the exception:
java.io.IOException: Stream closed
at java.base/java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:176)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:342)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at Q2Server.run(Q2Server.java:65)
at java.base/java.lang.Thread.run(Thread.java:835)
When either of the server or client sends "close" the connection closes. The client can connect again. But when I run the client code again, I get the exception. What is going wrong and how do I fix this?
You're getting an exception because you're trying to read from a BufferedReader which no longer exists, the in1 in particular. At the first run, all your streams and readers open as they should, but after getting the command close from the client, your server closes the in1. Then, when the client tries to reconnect, the program tries to assign the value of in1.readLine() to serverMsg which is a String, but since in1 is no more, the IOException occurs since the BufferedReader is closed and nothing can be read from it.
I suppose since you want to leave the server running while the client(s) can connect and disconnect at any given time, which totally makes sense, maybe you shouldn't close the BufferedReader which supplies keyboard commands to the server in your case. Closing it doesn't make sense to me, since you're not stopping the whole server when the client disconnects, you just close the connection, but the server still should be able to accept commands.
Hope this helps.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I have been "googeling" around for a long time for examples over Server-client-chat application, but I can't really understand them. Many of them are using a class and creates the GUI from it, and I don't want to copy straight from it. Alot of examples doesn't either really explain how you send messages from a client to the server and then it sends the message out to all the other clients.
I am using NetBeans and I was wondering if there is some good tutourials or examples that can help me with this?
Here comes the multiThreading program :) the server has two classes, and client has one. Hope you Like it!
SERVER MAIN CLASS:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
int MAXCLIENTS = 20;
int port = 4444;
ServerSocket server = null;
Socket clientSocket = null;
// An array of clientsConnected instances
ClientThread[] clientsConnected = new ClientThread[MAXCLIENTS];
try {
server = new ServerSocket(port);
System.out.println("listening on port: " + port);
} catch (IOException e) {// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
clientSocket = server.accept();
} catch (IOException e) {
e.printStackTrace();
if (!server.isClosed()){server.close();}
if (!clientSocket.isClosed()){clientSocket.close();}
}
System.out.println("Client connected!");
for (int c = 0; c < clientsConnected.length; c++){
if (clientsConnected[c] == null){
// if it is empty ( null) then start a new Thread, and pass the socket and the object of itself as parameter
(clientsConnected[c] = new ClientThread(clientSocket, clientsConnected)).start();
break; // have to break, else it will start 20 threads when the first client connects :P
}
}
}
}
}
SERVER CLIENT CLASS:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ClientThread extends Thread{
private ClientThread[] clientsConnected;
private Socket socket = null;
private DataInputStream in = null;
private DataOutputStream out = null;
private String clientName = null;
//Constructor
public ClientThread(Socket socket, ClientThread[] clientsConnected){
this.socket = socket;
this.clientsConnected = clientsConnected;
}
public void run(){
try {
// Streams :)
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String message = null;
clientName = in.readUTF();
while (true){
message = in.readUTF();
for (int c = 0; c < clientsConnected.length; c++){
if (clientsConnected[c]!= null && clientsConnected[c].clientName != this.clientName){ //dont send message to your self ;)
clientsConnected[c].sendMessage(message, clientName); // loops through all the list and calls the objects sendMessage method.
}
}
}
} catch (IOException e) {
System.out.println("Client disconnected!");
this.clientsConnected = null;
}
}
// Every instance of this class ( the client ) will have this method.
private void sendMessage(String mess, String name){
try {
out.writeUTF(name + " says: " + mess);
} catch (IOException e) {
e.printStackTrace();
}
}
}
AND FINALLY THE CLIENT:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException {
Main m = new Main();
m.connect();
}
public void connect() throws IOException{
//declare a scanner so we can write a message
Scanner keyboard = new Scanner(System.in);
// localhost ip
String ip = "127.0.0.1";
int port = 4444;
Socket socket = null;
System.out.print("Enter your name: ");
String name = keyboard.nextLine();
try {
//connect
socket = new Socket(ip, port);
//initialize streams
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
//start a thread which will start listening for messages
new ReceiveMessage(in).start();
// send the name to the server!
out.writeUTF(name);
while (true){
//Write messages :)
String message = keyboard.nextLine();
out.writeUTF(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!socket.isClosed()){socket.close();}
}
}
class ReceiveMessage extends Thread{
DataInputStream in;
ReceiveMessage(DataInputStream in){
this.in = in;
}
public void run(){
String message;
while (true){
try {
message = in.readUTF();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I ran the server in eclipse, and started two clients from the CMD, looks like this:
Here is a super simple I made just now with some comments of what is going on. The client connects to the server can can type messages which the server will print out. This is not a chat program since the server receives messages, and the client send them. But hopefully you will understand better it better :)
Server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static DataInputStream in;
public static DataOutputStream out;
public static void main(String[] args) throws IOException {
int port = 4444;
ServerSocket server = null;
Socket clientSocket = null;
try {
//start listening on port
server = new ServerSocket(port);
System.out.println("Listening on port: " + port);
//Accept client
clientSocket = server.accept();
System.out.println("client Connected!");
//initialize streams so we can send message
in = new DataInputStream(clientSocket.getInputStream());
out = new DataOutputStream(clientSocket.getOutputStream());
String message = null;
while (true) {
// as soon as a message is being received, print it out!
message = in.readUTF();
System.out.println(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!server.isClosed()){server.close();}
if (!clientSocket.isClosed()){clientSocket.close();}
}
}
}
Client:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Main
{
public static void main(String[] args) throws IOException {
//declare a scanner so we can write a message
Scanner keyboard = new Scanner(System.in);
// localhost ip
String ip = "127.0.0.1";
int port = 4444;
Socket socket = null;
try {
//connect
socket = new Socket(ip, port);
//initialize streams
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while (true){
System.out.print("\nMessage to server: ");
//Write a message :)
String message = keyboard.nextLine();
//Send it to the server which will just print it out
out.writeUTF(message);
}
}
catch (IOException e){
e.printStackTrace();
if (!socket.isClosed()){socket.close();}
}
}
}
I am trying to launch server and client thread on the same process, but seems like the server thread is blocking the client thread (or vice versa). I'm not allowed to use any global variable between those threads(like semaphore or mutex, since the client and the server thread are launched by upper-class that I don't have the access of).
I found a similar question here , but it still use two different process (two main function).
Here is a sample of my code
The server code:
public class MyServer implements Runnable{
ServerSocket server;
Socket client;
PrintWriter out;
BufferedReader in;
public MyServer() throws IOException{
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while(true){
try {
ArrayList<String> toSend = new ArrayList<String>();
System.out.println("I'll wait for the client");
client = server.accept();
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null){
toSend.add("answering : "+inputLine);
}
for(String resp : toSend){
out.println(resp);
}
client.close();
out.close();
in.close();
} catch (IOException ex) {
}
}
}
}
And the client code:
public class MyClient implements Runnable{
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient(){
}
#Override
public void run() {
int nbrTry = 0;
while(true){
try {
System.out.println("try number "+nbrTry);
socket = new Socket(InetAddress.getByName("localhost"), 15243);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("Hello "+nbrTry+" !! ");
String inputLine;
while((inputLine = in.readLine()) != null){
System.out.println(inputLine);
}
nbrTry++;
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
And the supposed upper-class launching those thread:
public class TestIt {
public static void main(String[] argv) throws IOException{
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
It gives me as output:
I'll wait for the client
Try number 0
And it stuck here. What should I do to keep both server and client code running?
Thank you.
I'll be willing to take up your questions but basically you need to think through your logic a bit more carefully.
MyServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer implements Runnable {
ServerSocket server;
public MyServer() throws IOException {
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while (true) {
try {
// Get a client.
Socket client = server.accept();
// Write to client to tell him you are waiting.
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("[Server] I'll wait for the client");
// Let user know something is happening.
System.out.println("[Server] I'll wait for the client");
// Read from client.
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine = in.readLine();
// Write answer back to client.
out.println("[Server] Answering : " + inputLine);
// Let user know what it sent to client.
System.out.println("[Server] Answering : " + inputLine);
in.close();
out.close();
client.close();
} catch (Exception e) {
}
}
}
}
MyClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClient implements Runnable {
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient() throws UnknownHostException, IOException {
}
#Override
public void run() {
int nbrTry = 0;
while (true) {
try {
// Get a socket
socket = new Socket(InetAddress.getByName("localhost"), 15243);
// Wait till you can read from socket.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine = in.readLine();
//inputLine contains the text '[Server] I'll wait for the client'. means that server is waiting for us and we should respond.
// Write to socket
out = new PrintWriter(socket.getOutputStream(), true);
out.println("[Client] Hello " + nbrTry + " !! ");
// Let user know you wrote to socket
System.out.println("[Client] Hello " + nbrTry++ + " !! ");
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
TestIt.java
import java.io.IOException;
public class TestIt {
public static void main(String[] argv) throws IOException {
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
Your client sends a string, then reads until the stream is exhausted:
while((inputLine = in.readLine()) != null){
BufferedReader.readLine() only returns null at the end of the stream, as I recall. On a stream, it will block until input is available
Your server receives until the stream is exhausted, then sends back its response.
After sending one line, you now have:
Your client waiting for a response.
Your server still waiting for more data from the client. But it doesn't send anything back until the end of the stream from the client (which never happens because the client is waiting for your response).
hi i writ acode for client and for server and now i want to deliver the message between clint one to clint two and i dont succees to do this on server side i want to construct array for name and id and after i send message from the client side i can choose where or Which name the server deliver the message pleas help me to writ this
so this is the clint side
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class client {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 7777);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader readerFromCommandLine = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.println("Say something:");
String userInput = readerFromCommandLine.readLine();
writer.println(userInput);
writer.flush();
String input = reader.readLine();
System.out.println("Got from server: "+input);
if (userInput.equalsIgnoreCase("bye")) {
break;
}
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch (Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
so now my code shuold by look like this ?
becaus i not yet can send from one client to client two
import java.awt.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class server {
public static void main(String[] args) {
ArrayList<Channel> my_clients = new ArrayList<Channel>();
ServerSocket ss = null;
try {
ss = new ServerSocket(7777);
while (true) {
//wait for a new client call - once got it, get the socket for
//that channel
System.out.println("Waiting for an incoming call");
Socket client = ss.accept();
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
//once the call has started read the client data
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
//my_client.writer("HELLO!");
}
}
//System.out.println("Accepted a new call");
//new Channel(client).start();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (ss != null) {
try {
ss.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
public static class Channel extends Thread {
private static int clientIndex = 0;
private int index;
private Socket socket = null;
public Channel(Socket socket) {
clientIndex++;
index = clientIndex;
this.socket = socket;
}
#Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while (true) {
String input = reader.readLine();
System.out.println("Got from client "+index+": "+input);
//bye bye
if (input.equalsIgnoreCase("bye")) {
break;
}
writer.println("Gotcha");
writer.flush();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
}
String userInput = readerFromCommandLine.readLine();
BufferedReader.readLine() is a problem here. It is going to block your thread until input is received. This means communication can only ever go in one direction at a time, and can potentially get totally blocked if both clients are waiting.
DataFetcher can fix this problem; you can use it to listen in a separate Thread
http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/
You half way there.
You created a Threaded Server were each connection from a client opens a thread. This thread then loops and waits for messages.
Think of these threads as you connected clients with their own objects / properties and their streams to write to and read from them.
So each time a clients connections you want to create their thread add it to some kind of list and start their thread. For example:
At the top of the class
List<Channel> my_clients = new List<Channel>();
In your while loop
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
Then when you want to send a message to a certain clients. You can loop all the Threads and look for one that has some kind of name or Unique Indentifier. For example:
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
my_client.write("HELLO!");
}
}
or in the same breath you could send a message to all your clients (Broadcast):
for(Channel my_client : my_clients) {
my_client.write("HELLO!");
}
remember to remove the clients when they disconnect too!
// Can't remember the precise exception correct my if I'm wrong!
catch(SocketException ex) {
my_clients.remove(this);
}
Note this expects that you some how authenticate and know the name of your client or supply them a UID which you reference when you are instructed to sent them something. And that the Channel class has the Write Method for connivance.
Hope that Help!