I have read through most similar questions in Stack-overflow . But i can't find similar one.
I build one client and one server. For my client networking, i build a class which contains a socket and many relevant methods like this :
public class Connector {
private Socket socket;
private DataOutputStream output;
private DataInputStream input;
public Connector(int x) throws UnknownHostException, IOException{
socket=new Socket("localhost",x);
}
public boolean isConnected(){
return socket.isConnected();
}
public void sendInfo(String str) throws IOException{
output = new DataOutputStream(socket.getOutputStream());
output.writeUTF(str);
output.flush();
}
public String receiveInfo() throws IOException{
input = new DataInputStream(socket.getInputStream());
return input.readUTF();
}
public boolean loginSuccess() throws IOException{
input = new DataInputStream(socket.getInputStream());
return input.readBoolean();
}
}
and when my client runs(the server run in my IDE),
String userAccount = "VerifyAccount" + "#" + userNametf.getText() + "#" + passwordtf.getText() + "#" + i;
connector.sendInfo(userAccount);
if(connector.isConnected())
System.out.println("the connector is still connected!");
else
System.out.println("the connector is no connected!");
if(connector.loginSuccess()){
System.out.println("Log in success");
}
else;
and this is my server:
ServerSocket serverSocket = new ServerSocket(8000);
while(true){
Socket socket = serverSocket.accept();
Thread thread = new Thread(()->{
try{
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
String tempStr = input.readUTF();
System.out.println("Server receive data : "+tempStr);
String[] tempStrArray = tempStr.split("#");
if(tempStrArray[0].equals("VerifyAccount")){
if(UserVerification.isValid(tempStr.substring(14))==1){
output.writeBoolean(true);
output.flush();
}
else{}
}
else if(tempStrArray[0].equals("RegisterAccount")){}
else{}
}
catch(IOException ex){
ex.printStackTrace();
}
});
thread.start();
}
So the whole process is that the client socket connects to the server socket ,
then client send one string to the server , the server process the string , and write a boolean value back to the client , but when i call connector.LoginSuccess() , the compiler will throw an exception like this:enter image description here
You are never closing the accepted socket. You are also attempting to read a boolean that may never be sent. And, as I said in comments, isConnected() doesn't do what you think it does: it doesn't magically start returning false when the peer disconnects.
Related
currently I am trying to send multiple messages from a client to a server and echo them on the server but somehow my message is not arriving at the server until i press CTRL+Z(D) and hit enter.
My loop runs as long as the user does not enter "quit" but altough I write my message to the OutputStream and flush it my message does not show on the Server side as if my Client still reads input.
(I do not want to use BufferedReaders or Threads at the moment it's purely for learning reasons.)
Would be nice if someone could tell me where my mistake/error lies.
Read also the javadocs but still can not find my mistake.
Client.java
public class Client {
//class members
private String msg = null;
private Scanner scn = null;
public Client(String ip, int port) throws IOException {
//Connect to Server
try(Socket socket = new Socket(ip,port))
{
//Initialize class members
scn = new Scanner(System.in); //Init Scanner
msg="";
System.out.println("Enter message:");
//Write to Socket
OutputStream out = socket.getOutputStream();
while(!msg.equals("quit"))
{
msg=scn.nextLine();
out.write(msg.getBytes(), 0, msg.length());
out.flush();
}
}
catch (IOException ex)
{
System.err.println(ex);
}
}
Server.java
public class Server {
//class members
private String msg = null;
public Server(int port) throws IOException {
//Setup ServerSocket.
ServerSocket server = new ServerSocket(port);
System.out.println("SERVER: Launched service.");
//Accept incoming connection requests.
while(true) {
try(Socket connection = server.accept())
{
System.out.println("SERVER: Client connection accepted.");
//Read Input
StringBuilder line = new StringBuilder();
InputStream in = connection.getInputStream();
for(int c=in.read(); c!=-1; c=in.read())
{
line.append((char) c);
}
System.out.println(line);
}
catch (IOException ex)
{
System.out.println("SERVER: Client disconnected!");
}
}
}
sincerely,
rhyleigh
Your server prints nothing until read() returns -1.
read() returns -1 at end of stream.
Over a TCP socket, end of stream is only caused by the peer closing the connection.
Your server's peer, i.e. the client, doesn't close the connection until you type ^Z at the terminal. which causes an unstated exception to be thrown.
Your program is working as designed.
Here I am creating a thread to check for a server response every 2 seconds, the issue is that the client.monitorResponse() is a readLine() method and will not continue until a response is received.
client = new ClientObject("localhost");
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
String response = null;
if(!(response = client.monitorResponse()).isEmpty()) {
System.out.println("Response: " + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 2000, 2000);
I am sending the response via the Server like so (where client is a established Socket):
public SocketObject(Socket client, int numberOfClients) throws Exception {
socket = client; // the .accept() socket is passed through
// this is because I assign them ID's for later use (I hold an ArrayList of sockets)
this.clientId = numberOfClients;
// both these are static to the class
outputStream = new PrintWriter(client.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
}
public void sendResponse(String response) {
outputStream.println(response);
}
I am then picking the response up via the client Socket that has connected to the server:
public ClientObject(String hostname) throws IOException {
// socket is static to this class
socket = new Socket(hostname, 4444);
System.out.println("Connected to " + hostname + " on port 4444...");
// both static to this class
outputStream = new PrintWriter(socket.getOutputStream(), true);
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Successfully started a stream on " + hostname);
this.hostname = hostname;
}
public String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
return inputStream.readLine();
}
The debug console only displays the Listening for a response... output once which is telling me that it doesn't get past the inputStream.readLine() method in-side the Thread. Is there anyway I can add a timeout on the BufferedReader? I have tried multiple solutions like adding a .setSoTimeout() to the socket before creating the BufferedReader but all that did was close the connection/socket after the specified time.
Any help would be appreciated.
You should use a non-blocking (NIO) request and read chunks looking for newlines in-between. Typically in Java you just have to look for the NIO version of the Stream class you are using and use it to check every N seconds for new content. In your case with minimal modifications you can use the less fancy and efficient method of blocking calls with BufferedReader.ready() to prevent blocking:
String partialLine="";
public static String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
int nextByte;
String nextChar;
while (inputStream.ready()) {
nextByte = inputStream.read();
nextChar = Character.toString ((char) nextByte);
partialLine += nextChar;
if ("\n".equals(nextChar)) {
String line = partialLine;
partialLine = "";
return line.replace("\r\n", "");
}
}
return "";
}
Check out http://tutorials.jenkov.com/java-nio/nio-vs-io.html for more info.
Is there anyway I can add a timeout on the BufferedReader?
No, but you can set a timeout on the Socket, with Socket.setSoTimeout().
I have tried multiple solutions like adding a .setSoTimeout() to the socket before creating the BufferedReader but all that did was close the connection/socket after the specified time.
No it doesn't close the socket. It throws SocketTimeoutException, which you should catch and handle as pertinent. If the socket is being closed, you're closing it. Solution: don't.
Hello stackoverflow community,
i am stuck at a problem regarding socket communication in Java.
Here is the sample code of my Server and Client class:
Server:
public class OTPServer {
static ServerSocket serverSocket;
final static int PORT = 4242;
static Socket clientConnection;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Socket initialized");
String serverMessage = "Hello, I am the Host";
ServerTool serverTool = new ServerTool();
while (true) {
clientConnection = serverSocket.accept();
if(clientConnection.isConnected()) {
System.out.println("Client connected");
}
BufferedReader clientInputReader = new BufferedReader(new InputStreamReader(clientConnection.getInputStream()));
DataOutputStream serverOutput = new DataOutputStream(clientConnection.getOutputStream());
System.out.println("Sending message to client: " + serverMessage);
serverOutput.writeBytes(serverTool.encodeMessage(serverMessage));
serverOutput.flush();
String clientMessage = clientInputReader.readLine();
System.out.println("Encoded answer from client: " + clientMessage);
String decodedMessage = serverTool.decodeMessage(clientMessage);
System.out.println("Decoded answer from client: " + decodedMessage);
serverOutput.close();
clientInputReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Hello, I am the OTP Server!");
}
Here is the Client:
public class OTPClient {
static Socket clientSocket;
final static int PORT = 4242;
final static String HOST = "localhost";
public static void main(String[] args) {
System.out.println("I am the OTP Client!");
String serverMessage;
String clientResponse = "I am the Client";
OTPTool otpTool = new OTPTool();
try {
clientSocket = new Socket(HOST, PORT);
BufferedReader serverInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Connection to Host established");
serverMessage = serverInput.readLine();
System.out.println("Encoded Message from Server: " + serverMessage);
String decodedMessage = otpTool.decodeMessage(serverMessage);
System.out.println("Decoded message from Server: " + decodedMessage);
System.out.println("Answering with own message: " + clientResponse);
outputStream.writeBytes(clientResponse);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Now where is my problem:
The connection establishes and the Server seems to send its message to the client and waits for a answer. The Client does not print the message he got from the Server.
As soon as i cancel the Server the client prints the message it gets from the server as well as the information, that the answer is send end exits with exit code 0 so it seems that this part is fine it just is stuck somehow.
I already tried to flush the outputStream as you see in the example code given.
Is there something obvious im missing?
I know, this is really basic stuff but its my first time using sockets for communication.
Thank you in advance!
Best Regards,
Ronny
Btw: i know that the server only connects to one client requesting a connection. Thats absolutely sufficient for my use.
It is getting stuck because serverInput.readLine(); blocks until either a line break or end of file is encountered. On the server side, you are not sending a line break, so the client blocks.
I'm trying to program a Server Client program where the CLIENT will be prompt if the SERVER closes or loses connection. What happens is once I connect the server and the client then disconnects the server it doesn't go to the ConnectException part
example: I opened the Server and Client connects, in the Client it will show that "You are connected to the Server", then if the Server disconnects there should be a "Server is disconnected". and when the Server reopens it will prompt the Client that he's connected to the Server
How can I continuously check if the Server is open or disconnected
here's my code:
SERVER
public class Server
{
private static Socket socket;
public static void main(String[] args)
{
try
{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
//Server is running always. This is done using this while(true) loop
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("Client has connected!");
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
CLIENT
public class Client
{
private static Socket socket;
public static void main(String args[])
{
Scanner input=new Scanner(System.in);
try
{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
System.out.println("Connected to the Server");
}
catch (ConnectException exception)
{
System.out.println("Server is still offline");
}
catch(IOException ex)
{
System.out.println("Server got disconnected");
}
}
}
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
you can do like this
try
{
Socket s = new Socket("address",port);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
or you can simply et connection time out like this socket.setSoTimeout(timeout); to check connectivity
or you can use
socket.getInputStream().read()
makes the thread wait for input as long as the server is connected and therefore makes your program not do anything - except if you get some input and
returns -1 if the client disconnected
or what you can do is structure your code in this way
while(isConnected())
{
// do stuffs here
}
I'm learning java. I'm trying to make a simple client/server chat system. What I have so far is a program where the server accepts multiple client connections by giving them each a seperate thread.
My problem now, is that I can't figure out how to get an input from one client, and then have it be sent amongst all of the clients, thus essentially have a very very simple chat mechanic. How would I go about accomplishing this? What would be the simpler way?
My code so far is here;
class Client {
public static void main(String argv[]) throws Exception {
String sentMessage; //variable for input
String receivedMessage; //variable for output
String status;
boolean running;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 5622); //name of computer to connect with and port number to use
DataOutputStream outToServer =
new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer =
new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Client Side\n");
running = true;
while(running)
{
sentMessage = inFromUser.readLine(); //user inputs text to variable 'xInput'
outToServer.writeBytes(sentMessage + '\n'); //the variable is sent to the server
status = inFromServer.readLine();
System.out.println("FROM SERVER: " + status); //display to user
}
clientSocket.close();
}
}
The server code.
class Server {
public static void main(String argv[]) throws Exception {
String clientMessage;
boolean listening = true;
int portNumber = 5622;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
while (listening) {
new ServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
The thread that handles the client connections.
public class ServerThread extends Thread {
private Socket socket = null;
public ServerThread(Socket socket) {
super("ServerThread");
this.socket = socket;
}
public void run () {
int msgCnt = 0;
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
//something needs to go here
} catch (IOException e) {
e.printStackTrace();
}
}
If you are looking for a simple client-server communication samples then please have a look at below posts where I have described it step by step.
Multiple clients access the server concurrently
Java Server with Multiclient communication.