I have implemented a chat using Client-Server model in Java. However, I have this one problem with dos.writeUTF(msgout) where dos is a DataOutputStream object.
Let's say Client 1 and Client 2 connect to the Server. Server is able to handle messages from both clients in its DataInputStream. However, when writing back, the server will only send the message to the last client (this case 2). The connection with Client 1 stays established, but it's like Server 'forgets' about Client 1. I do not want to broadcast, but I just want to know how can I dos.writeUTF(msgout) to e.g. the first Client? Here is my piece of code from the Server.
Static variables (i'm using Swing as GUI):
static DataOutputStream dos;
static DataInputStream dis;
static Vector<ClientHandler> ar = new Vector<>(); // Vector for active clients
static int i = 0; // Client counter
The piece from the main method where connection is settled:
ServerSocket ss = new ServerSocket(1234);
Socket s;
while (true) {
s = ss.accept();
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
ClientHandler mtch = new ClientHandler(s, "Client" + (i+1), dis, dos);
Thread t = new Thread(mtch);
ar.add(mtch); // Add client to active clients
t.start();
i++;
}
I have made a method to send messages (when I click a button):
public void send() {
try {
String msgout = "";
msgout = txtChat.getText().trim();
if (!msgout.equals("")) {
dos.writeUTF(msgout); // Need to get specific here. How to write to Client's 1 DataInputStream?
}
} catch (Exception e) {
//
}
}
ClientHandler class is found here https://pastebin.com/NWms7TfF
This is not good:
static DataOutputStream dos;
followed by:
dos.writeUTF(msgout);
You're creating a single static DataOutputStream field and then wondering why using this field only represents one output stream. First of all, you should get rid of the static fields, although this won't solve your problem (but it might help fix others). Instead if you want to write to a specific output stream, you need a way to get a reference to it. Consider creating a HashMap to hold your ClientHandler objects, and add them to the Map using whatever unique identifier you wish to use that would help you retrieve them, perhaps a clientName String field or a clientId String field (don't use numbers for id). And assuming that ClientHandler has a getDos() method that returns its output stream (if it doesn't have this then it should get one). Then you can get the ClientHandler from the Map when needed, extract its output Stream via getDos(), and then write to it.
Side note, it is not appropriate to post links to code bases. Instead please post all relevant code in your question.
I'm trying to send an message from Java client to C++ server using ProtoBuf over socket. My program hangs while i am trying to create InputStream. Thanks in advance if some one could help me on this and here is my part of client code in java:
String host = "xxxxxxxxx";
int port = xxxx;
Builder builder = CarSelection.Car.newBuilder();
builder.setLabel("Audi");
builder.setValue("A6");
Car car = builder.build();
Socket client = new Socket(host, port);
byte[] result = car.toByteArray() ;
car.writeDelimitedTo(client.getOutputStream());
Car recieveData= car.parseDelimitedFrom(client.getInputStream());
It is able to write to output stream but my program hangs when trying to read from input stream.
I tried to find in exact solution for this problem but I'm not able to find it
I have written a while loop to accept client sockets in server program
because of this I'm unable to close the serversocket as it is always listening
here is my server code
public class nserver {
public static void main(String[] args) throws IOException {
int port=4413;
//server is running on port
try(ServerSocket ss = new ServerSocket(port)){;
// socket accepts data from the incoming clients
while(true){
Socket socket = ss.accept();
// id I don't put the if case then this loop never breaks and
// although I wrote ss.close() - it will never reached - so use if case
if(socket.equals(null))
break;
System.out.println("Server is running on port "+port);
//socket.getInetAddress gives address of client ip not the server ip as the socket is mada as client socket
System.out.println("server recieved connection from "+socket.getInetAddress()+" : "+socket.getPort());
//create two threads to send and receive from client
rxClientData rx = new rxClientData(socket);
Thread t = new Thread(rx);
t.start();
sdServerData sd = new sdServerData(socket);
Thread t2 = new Thread(sd);
t2.start();
// if I put ss.close() here then it will accept only one client socket and serversocket will be closed after this line
}
ss.close();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
how to close serversocket after my client socket requests,I have 3 clients
with for loop I will have a limit of no.of client sockets,but a server should accept so many no.of requests - so I used while loop
for a server do we need to keep serversocket open in real world scenario ? - so that it accepts client requests all the time
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am currently learning about Sockets and my homework is to create a chat room where multiple clients can talk freely. The hint given by the teacher was that the chat room server only accepts the client when the client attempts to send a message. This homework is supposed to be done without using threads.
Following the hint given, I tried to create unbound ServerSocket and Socket in both the client and the server code. The key idea is that when the client attemps to send a message to the server, the client code would connect the unbound Socket, which will then trigger the server to connect the unbound ServerSocket and to accept the client.
However, when I run the code, both the server and client code are running, and they claim that all the connections are made, but I could not transmit messages between the client and the server at all.
I have tried finding answers online, but I could not find any. I would like to ask if my way of deciding when the server accepts the client is correct.
my ChatRoom Server:
public class ChatRoom {
public static void main(String[] args) throws Exception {
int portNum = 4321;
ServerSocket serverSocket = new ServerSocket();
int count = 1;
while (true) {
// redeclare everything each round
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader stdIn = null;
String inputLine = null;
// accept each time round
serverSocket.bind(new InetSocketAddress(portNum));
socket = serverSocket.accept();
System.out.println("newly accepted!");
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
if (!((inputLine = in.readLine()).equals("Bye"))) {
System.out.println("Client says: " + inputLine);
out.println(stdIn.readLine());
out.flush();
System.out.println("Message Count: " + count);
count++;
}
else {
out.println(inputLine);
serverSocket.close();
socket.close();
out.close();
in.close();
}
}
}
}
my ChatRoomClient:
public class ChatRoomClient {
public static void main(String[] args) throws Exception {
String hostName = "localhost";
int portNumber = 4321;
Socket echoSocket = new Socket(); // creates an unbound socket
PrintWriter out = null;
BufferedReader in = null;
BufferedReader stdIn = null;
String userInput;
do {
out = null;
in = null;
stdIn = null;
// each time round the unbound socket attempts to connect to send a message
echoSocket.connect(new InetSocketAddress(hostName, portNumber));
System.out.println("successfully connected");
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
userInput = stdIn.readLine();
out.flush();
System.out.println("Server says: " + in.readLine());
}
while (!userInput.equals("Bye"));
// close everything
echoSocket.close();
in.close();
stdIn.close();
}
}
Thanks!
The hint given by the teacher was that the chat room server only accepts the client when the client attempts to send a message. This homework is supposed to be done without using threads.
The hint given by the teacher doesn't make sense. The client has to connect, then the server accepts. The client can't send a message without connecting first. Maybe the teacher really means that the client shouldn't connect until he has something to send?
Following the hint given, I tried to create unbound ServerSocket and Socket in both the client and the server code. The key idea is that when the client attemps to send a message to the server, the client code would connect the unbound Socket, which will then trigger the server to connect the unbound ServerSocket and to accept the client.
But that won't happen. It's impossible. If you try to connect to a port that isn't listening, you will get a ConnectException. The only way to put the port into listening state is to bind the ServerSocket. There is no magical back-door by which the server can possibly know that the client wants to connect so it should now do the bind.
This homework is supposed to be done without using threads.
Impossible to 'create a chat room where multiple clients can talk freely' that way, unless you are expected to use non-blocking I/O, or abuse the available() facility, or use a connection per message, but then I don't see how you can communicate one client's messages to the other clients, unless you're allowed to batch them up.
There are too many imponderable aspects of this assignment as you have described it. The question as posed doesn't actully make sense, and your proposed solution certainly doesn't. You should just go ahead and write your program the normal way, with a connect, an accept, and some I/O. Get it working while your teacher comes up with a clarification.
Ah... With out using thread for the server you will not be able to serve multiple clients. Anyway, your current codes have issues and your logic are not correct.
Your stdIn should be declare and instantiated outside of the loop, you don't need to keep on creating the stdIn object for each loop.
Your "in" socket accept() and echoSocket.connect() should also be outside of the loop, this is why you are not getting any answer from the server because you are not listening on the same line. It's like your phone, keep on FLASH to dial the new number each time. all point to the same server, but it is different connection.
So, the idea is to establish a connection between server and client (single connection) that can communicate both way (via input and output stream). Then you can loop and talk start with the client, then server receive, then server talk, then client receive then client talk.... until client say Bye...
for more: http://ta.cnci.org/basicirc
thought I would like to update, I managed to solve my problem without using threads. Just sockets haha. Thought it would be good to post my answer for reference..
my ChatRoom Server:
public class ChatRoomServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(4321);
while(true) {
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader
(new InputStreamReader(clientSocket.getInputStream()));
String inputLine = in.readLine();
System.out.println("Client says: " + inputLine);
in.close();
clientSocket.close();
}
}
}
my ChatRoom Client:
public class ChatRoomClient {
public static void main(String[] args) throws Exception {
String hostName = "localhost";
int portNum = 4321;
BufferedReader stdIn = new BufferedReader
(new InputStreamReader(System.in));
while (true) {
String userInput;
userInput = stdIn.readLine();
Socket echoSocket = new Socket(hostName, portNum);
PrintWriter out = new PrintWriter
(echoSocket.getOutputStream(), true);
out.println(userInput);
out.flush();
out.close();
echoSocket.close();
if (userInput.equals("Bye")) {
stdIn.close();
break;
}
}
}
}
i have a simple server...
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(2000);
Socket sock = server.accept();
InputStream in = sock.getInputStream();
OutputStream out = sock.getOutputStream();
PrintWriter w = new PrintWriter(out);
Scanner s = new Scanner(in);
...
and a simple client...
public static void main(String[] args) throws Exception{
Socket sock = new Socket("localhost",2000);;
InputStream in= sock.getInputStream();
OutputStream out = sock.getOutputStream();
PrintWriter w = new PrintWriter(out);
Scanner s = new Scanner(in);
....
-how can i connect more clients to this server? (I need 2 more)
-also i want to send system time from server to clients and then clients will send
back their time 10 times each plus some fixed delay (0.5-1 sec) then the server must find the average from all delays and send it back to the clients as the new time...
thank you for your time...
System.currentTimeMillis() provides the system time
Every Socket returned by server.accept() is a separate object and your server can communicate independently with each client through each Socket object. However, since your application is time-sensitive, I would recommend using a separate thread for each client.
A simple server would be:
ServerSocket serverSock = new ServerSocket(2000);
while (true)
{
Socket fpSock = serverSock.accept();
MyThread t = new MyThread(fpSock, this);
t.start();
}
The processing you need will be done in the MyThread run() method. "this" is passed to the thread to provide a reference where each thread can callback to methods in the main class. Make sure to make such methods synchronized.
You also don't necessarily need to send the server's time to the client, simply send a generic packet which the client is expected to echo back. Use the server's timestamp for all transactions to avoid variation in client system time.