ask about deliver message between client to client - java

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!

Related

Sending a Message to Multiple Clients from One Server Simultaneously?

I am currently working on a TCP Sockets program in Java in which two or more separate clients connect to a single server, and that server will send a message to both of these connected clients simultaneously.
I've tried to work through the code multiple times, but I can't quite seem to be able to have one message be sent to both clients.
Below is a reduced version of my entire code, condensed down to just the issue I'm having.
I've also included a video, just to save you the effort of having to copy and run my code!
[STREAMABLE LINK]
When one client is connected, I just have to write one message in the server, press send, and it shows up in the client.
When two clients are connected, I have to write two messages in the server and press send twice, and one message goes to one client and the other to the next client.
How can I make it so I only send one message from the server that goes to all clients?
I greatly appreciate any and all help.
SERVER CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Server class
class Server {
public class countLogic {
public static int client_count = 0;
}
public static void main(String[] args) {
System.out.println("[SERVER]");
ServerSocket server = null;
try {
server = new ServerSocket(1234);
server.setReuseAddress(true);
while (true) {
Socket client = server.accept();
countLogic.client_count++;
System.out.println("Client ("+countLogic.client_count+") connected: " + client.getInetAddress().getHostAddress());
ClientHandler clientSock = new ClientHandler(client);
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;
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
Scanner sc = new Scanner(System.in);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while (true) {
line = sc.nextLine();
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();
}
}
}
}
}
CLIENT CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
System.out.println("[CLIENT 1]");
try (Socket socket = new Socket("localhost", 1234)) {
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
System.out.println("Server: "+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

Java Server Client Semantics

I am new to java and network programming for the most part. I want to write a program that automatically backs up my texts to my computer whenever my phone connects to my home wifi.
I am working on creating java classes that will handle sending data over the network. Using some questions found here, I came up with this implementation but I have some questions regarding some of the methods used in what I learned from.
Two Questions Regarding this code
I totally used a question from SO for the send methods in my client. The sendText uses a new thread, but the sendFile doesn't. Any particular reason why?
2. At which point in the code does the server actually know when there has been a message sent to the port? Is it at the method accept() call or is it when the BufferStream readLine() is checked? Does accept just grab data and throw it into the buffer? null implying the data grabbed was not a signal sent from a client?
Does the accept() method block execution of the code until a connection attempt is made from a client?
Thanks!
KServ
//Used to launch the server
public class KServ {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java KServ <port number>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
KServer server = new KServer(port);
while (true) { //added this to keep the server polling for new data
server.run();
}
}
}
KServer
//Server class. Should handle data incoming
import java.net.*;
import java.io.*;
public class KServer {
private int port;
public KServer(int PORT) {
port = PORT;
}
public void run() {
try (
ServerSocket sSocket = new ServerSocket(port);
Socket cSocket = sSocket.accept();
PrintWriter out = new PrintWriter(cSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
) {
String input;
while ((input = in.readLine()) != null) {
System.out.println(input);
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port " + port + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
Client
//launches KClient object and uses it to send input from console to the server
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Client <ip number> <port number>");
System.exit(1);
}
String ip = args[0];
int port = Integer.parseInt(args[1]);
KClient client = new KClient(ip,port);
String msg;
Scanner inStream = new Scanner(System.in);
while((msg = inStream.nextLine()).length() > 0) {
client.sendText(msg);
}
}
}
KClient
//Will be used to establish connection with server and send data from phone
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class KClient {
private String server;
private int port;
public KClient(String Server,int Port) {
server = Server;
port = Port;
}
public void sendFile(String fileName) {
File file = new File(fileName);
FileInputStream fileInputStream;
BufferedInputStream bufferedInputStream;
OutputStream outputStream;
try {
client = new Socket(server,port);
byte[] bytes = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(bytes, 0, bytes.length);
outputStream = client.getOutputStream();
outputStream.write(bytes,0,bytes.length);
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Socket client;
private OutputStreamWriter outputStreamWriter;
public void sendText(String msg) {
System.out.println("Send Message!");
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(server,port);
outputStreamWriter = new OutputStreamWriter(client.getOutputStream(), "ISO-8859-1");
outputStreamWriter.write(msg);
outputStreamWriter.flush();
outputStreamWriter.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
BufferedReader inStream;
public boolean Shake() {
try {
client = new Socket(server,port);
inStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
I totally used a question from SO for the send methods in my client. The sendText uses a new thread, but the sendFile doesn't. Any particular reason why?
Unanswerable. Ask the author. Both sends can block. As the file is presumably longer than the text, it would have made more sense to do it the other way round.
2. At which point in the code does the server actually know when there has been a message sent to the port? Is it at the method accept() call
No.
or is it when the BufferStream readLine() is checked?
Yes.
Does accept just grab data and throw it into the buffer?
No. It grabs a connection and returns it as a socket. Nothing to do with data whatsoever.
null implying the data grabbed was not a signal sent from a client?
You seem to be actually asking about BufferedReader.readLine() here, not ServerSocket.accept(), which doesn't return null. readLine() returns null when there is no pending data to be read and the peer has closed the connection.
Does the accept() method block execution of the code until a connection attempt is made from a client?
More or less. It blocks until there is a complete connection waiting to be accepted, which isn't quite the same thing, as there is a queue.
I will add that you have copied, or written, some truly terrible code here. There are much better examples.

java multi client socket server echoing all clients

I was working on multi-client sockets and its working just fine, however it came to my mind on how to make the communication public by making the entered string being streamed to all clients.
e.g if there are lets say 3 clients A,B and C and client A sends "foo" to server, I want the server to stream "foo" to clients B and C as well.
The Server Module :
package multiclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) {
Socket s = null;
ServerSocket ss2 = null;
System.out.println("Server Listening......");
try {
ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined
} catch (IOException e) {
e.printStackTrace();
System.out.println("Server error");
}
while (true) {
try {
s = ss2.accept();
System.out.println("connection Established");
ServerThread st = new ServerThread(s);
st.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
class ServerThread extends Thread {
String line = null;
BufferedReader is = null;
PrintWriter os = null;
Socket s = null;
public ServerThread(Socket s) {
this.s = s;
}
public void run() {
try {
is = new BufferedReader(new InputStreamReader(s.getInputStream()));
os = new PrintWriter(s.getOutputStream());
} catch (IOException e) {
System.out.println("IO error in server thread");
}
try {
line = is.readLine();
while (line.compareTo("QUIT") != 0) {
os.println(line);
os.flush();
System.out.println("Response to Client : " + line);
line = is.readLine();
}
} catch (IOException e) {
line = this.getName(); //reused String line for getting thread name
System.out.println("IO Error/ Client " + line + " terminated abruptly");
} catch (NullPointerException e) {
line = this.getName(); //reused String line for getting thread name
System.out.println("Client " + line + " Closed");
} finally {
try {
System.out.println("Connection Closing..");
if (is != null) {
is.close();
System.out.println(" Socket Input Stream Closed");
}
if (os != null) {
os.close();
System.out.println("Socket Out Closed");
}
if (s != null) {
s.close();
System.out.println("Socket Closed");
}
} catch (IOException ie) {
System.out.println("Socket Close Error");
}
}//end finally
}
}
The Client Module:
package multiclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String args[]) throws IOException{
InetAddress address=InetAddress.getLocalHost();
Socket s1=null;
String line=null;
BufferedReader br=null;
BufferedReader is=null;
PrintWriter os=null;
try {
s1=new Socket(address, 4445); // You can use static final constant PORT_NUM
br= new BufferedReader(new InputStreamReader(System.in));
is=new BufferedReader(new InputStreamReader(s1.getInputStream()));
os= new PrintWriter(s1.getOutputStream());
}
catch (IOException e){
e.printStackTrace();
System.err.print("IO Exception");
}
System.out.println("Client Address : "+address);
System.out.println("Enter Data to echo Server ( Enter QUIT to end):");
String response=null;
try{
line=br.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
response=is.readLine();
System.out.println("Server Response : "+response);
line=br.readLine();
}
}
catch(IOException e){
e.printStackTrace();
System.out.println("Socket read Error");
}
finally{
is.close();os.close();br.close();s1.close();
System.out.println("Connection Closed");
}
}
}
The server can keep a collection of all client sockets (until one is closed). When a client message arrives, server writes it to all client sockets.
There's a problem though, socket.write() is blocking, so if we do it in a loop, a slow client will block the rest of the clients. You can spawn a new thread to write to each individual socket, if there aren't too many clients.
In the blocking IO world, to implement a true full-duplex protocol, it is necessary for server to have two threads per client, one for read, one for write.
You may also try NIO if you are brave enough...
There are many examples. Search for chat server. One good one if you don't mind using a framework is Netty, check the SecureChat example for working code. It is a short and focused example.
Edit: the link takes you to the example code.
I suggest:
1. Keep the threads you create in an ArrayList
2. Create a method in Server called writeString and a lock
private final Lock mutex = new ReentrantLock(true);
private ArrayList<ServerThread> list = new ArrayList<ServerThread>();
public void writeString(ServerThread t,String s)
{
mutex.lock();
for(ServerThread th:list)
if(th!=null && th!=t) //different from the thread receiving the string
th.writeString(s); //send string to other threads
mutex.unlock();
}
3. in ServerThread class, implement writeString method and add a Lock
private final Lock mutex = new ReentrantLock(true);
public void writeString(String s)
{
mutex.lock();
os.println(s);
os.flush();
mutex.unlock();
}
4. Keep a reference to the main Server thread by modifying the constructor
//in ServerThread
private Server parent=null;
SeverThread(Socket s, Server parent)
{
this.parent=parent;
/*the rest of the code*/
}
//in Server
ServerThread st = new ServerThread(s,this);
st.start();
list.add(st);
When you read the string in ServerThread, call the Server writeString method in order to notify all the clients
parent.writeString(this,s); //calls the method we created at 2.

Java Socket Server won't process second client

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;
}
}
}
}

Socket Issue - Only first message read

I am very new to sockets and was hoping someone could help me. I had something working but it was not sending information very quickly so i have refactored and now cannot get back to anything which works. The issue seems to be that only the first message that is published is read and then the receiver sits on client = listener.accept(); even though im pretty sure the sender is still sending messages
Can anyone see what i might be doing wrong here please?
Thanks
public class Sender {
Socket server = null;
DataInputStream inp = null;
PrintStream outp = null;
public Sender(){
server = new Socket("127.0.0.1" , 3456);
outp = new PrintStream(server.getOutputStream());
}
private void connectAndSendToServer(String message) {
outp = new PrintStream(server.getOutputStream());
outp.print(message + "\n");
outp.flush();
}
}
Receiver class
public class Receive{
public String receiveMessage(int port) {
String message= null;
ServerSocket listener = null;
Socket client = null;
try{
listener = new ServerSocket(port);
client = listener.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
return br.readLine();
}
...
finally{
try {
if(client!=null && listener!=null){
client.close();
listener.close();
}
}
catch (IOException e) {
}
}
return message;
}
}
This because a ServerSocket is used as an entry point for a normal Socket. accept() is a blocking operation that is usually done on a different thread compared to the one that receives/sends data to normal Socket. It sits there and waits for a new connection to spawn a new Socket which is then used for data.
This means that while receiving messages you should call just readLine() to read from the specific Socket. Having an accept inside the receiveMessage is wrong just because it's a different operation and it's even blocking.
Socket socket = serverSocket.accept();
ClientThread thread = new ClientThread(socket);
class ClientThread extends Thread {
Socket socket;
public void run() {
while (!closed) {
String line = reader.readLine();
...
}
}
You don't need to have a thread for every client though, but you need at least two for sure if you want to make your server accept a number of connections greater than 1.
You are not using ServerSocket correctly. You shouldn't create a new instance for every message but use it as a data member maybe and run an infinite loop to get a new client socket connection. Because you create it locally, the socket is closed since the object is no longer used and referenced (and so GC'ed), when you return from the method.
Something like (< condition met > is pseudo-code defines your condition to accept new connections):
while(< condition met >) {
try {
client = listener.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String str = br.readLine();
//do something with str
} finally {
//close client socket
}
}
Better approach will be to handle client socket in a different thread so the main thread is back to accept while you can do anything with the client socket in parallel.
Try this basic Chatting Server written by me. This server simply keeps running in loop and broadcast the message send by the clients to all the other clients associated with this server.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
// ///----------------------------------------Instance Variable Fields
ServerSocket ss = null;
Socket incoming = null;
// ///----------------------------------------Instance Variable Fields
// ///---------------------------------------- static Variable Fields
public static ArrayList<Socket> socList = new ArrayList<Socket>();
// ///---------------------------------------- static Variable Fields
public void go() {
try {
ss = new ServerSocket(25005);
while (true) {
incoming = ss.accept();
socList.add(incoming);
System.out.println("Incoming: " + incoming);
new Thread(new ClientHandleKaro(incoming)).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ClientHandleKaro implements Runnable {
InputStream is = null;
OutputStream os = null;
InputStreamReader isr = null;
BufferedReader br = null;
PrintWriter pw = null;
boolean isDone = false;
Socket sInThread = null;
public ClientHandleKaro(Socket sxxx) {
this.sInThread = sxxx;
}
#Override
public void run() {
if (sInThread.isConnected()) {
System.out.println("Welcamu Clienta");
System.out.println(socList);
}
try {
is = sInThread.getInputStream();
System.out.println("IS: " + is);
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
os = sInThread.getOutputStream();
pw = new PrintWriter(os, true);
String s = new String();
while ((!isDone) && (s = br.readLine()) != null) {
String[] asx = s.split("-");
System.out.println("On Console: " + s);
// pw.println(s);
Thread tx = new Thread(new ReplyKaroToClient(s,
this.sInThread));
tx.start();
if (asx[1].trim().equalsIgnoreCase("BYE")) {
System.out.println("I am inside Bye");
isDone = true;
}
}
} catch (IOException e) {
System.out.println("Thanks for Chatting.....");
} finally {
try {
Thread tiku = new Thread(new ByeByeKarDo(sInThread));
tiku.start();
try {
tiku.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Accha to hum Chalte hain !!!");
System.out.println(socList);
br.close();
pw.close();
sInThread.close();
} catch (IOException e) {
}
}
}
}
class ReplyKaroToClient implements Runnable {
public String mString;
public Socket mSocket;
public ReplyKaroToClient(String s, Socket sIn) {
this.mString = s;
this.mSocket = sIn;
}
#Override
public void run() {
for (Socket sRaW : socList) {
if (mSocket.equals(sRaW)) {
System.out.println("Mai same hun");
continue;
} else {
try {
new PrintWriter(sRaW.getOutputStream(), true)
.println(mString);
} catch (IOException e) {
System.out.println("Its in Catch");
}
}
}
}
}
class ByeByeKarDo implements Runnable {
Socket inCom;
public ByeByeKarDo(Socket si) {
this.inCom = si;
}
#Override
public void run() {
try {
new PrintWriter(inCom.getOutputStream(), true)
.println("You have Logged Out of Server... Thanks for your Visit");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server().go();
}
}

Categories

Resources