I have a problem which i've already been struggling for 3 days. I need to create server based on socket connection beetween the different local networks.
I found a lot of examples like this :
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
/**
* Created by yar 09.09.2009
*/
public class HttpServer {
public static void main(String[] args) throws Throwable {
ServerSocket ss = new ServerSocket(9999);
while (true) {
Socket s = ss.accept();
System.err.println("Client accepted");
new Thread(new SocketProcessor(s)).start();
}
}
private static class SocketProcessor implements Runnable {
private Socket s;
private InputStream is;
private OutputStream os;
private SocketProcessor(Socket s) throws Throwable {
this.s = s;
this.is = s.getInputStream();
this.os = s.getOutputStream();
}
public void run() {
try {
readInputHeaders();
writeResponse("<html><body><h1>Hello from Habrahabr</h1></body></html>");
} catch (Throwable t) {
/*do nothing*/
} finally {
try {
s.close();
} catch (Throwable t) {
/*do nothing*/
}
}
System.err.println("Client processing finished");
}
private void writeResponse(String s) throws Throwable {
String response = "HTTP/1.1 200 OK\r\n" +
"Server: YarServer/2009-09-09\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: " + s.length() + "\r\n" +
"Connection: close\r\n\r\n";
String result = response + s;
os.write(result.getBytes());
os.flush();
}
private void readInputHeaders() throws Throwable {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while(true) {
String s = br.readLine();
if(s == null || s.trim().length() == 0) {
break;
}
}
}
}
}
But problem is :
i can access to this ip:port only from the same local network. If i trying to connect from the same network (from Android smartphone to local computer which has the same network ip)? so in this case all is successful, but if i trying to run the same Server sample code on, say for example AWS (Amazon Web Server)
it doesn't work :(
-> Couldn't get I/O for the connection to 172.31.23.98 (java)
or
-> org.apache.http.conn.ConnectTimeoutException: Connect to 172.31.23.98:9999 timed out (groovy)
i'm using this sample code of Server :
public static void main(String[] args) throws IOException {
int portNumber = 9998;
BufferedOutputStream bos = null;
while (true) {
try (ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
InputStream in = clientSocket.getInputStream();
BufferedReader inWrapper = new BufferedReader(new InputStreamReader(in))) {
FileOutputStream fos = new FileOutputStream(new File("D:/BufferedAudio.wav"));
bos = new BufferedOutputStream(fos);
System.out.println("Connected with client");
String inputLine, outputLine;
int bytesRead;
byte[] buffer = new byte[1024 * 1024];
while ((bytesRead = in.read(buffer)) > 0) {
bos.write(buffer, 0, bytesRead);
System.out.println(new String(buffer, Charset.defaultCharset()));
bos.flush();
out.println("Hello!!! I'm server");
}
bos.close();
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
throw e;
}
System.out.println("Upps, the loop was unexpectedly out");
}
}
Here's the code of client :
public static void main(String[] args) throws IOException {
String IP = "172.31.23.98";
int port = 9998;
try (
Socket connectionSocket = new Socket(IP, port);
PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()))
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + IP);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
IP);
System.exit(1);
}
}
These are the samples from the internet.
Amm how can i modify this code to access from Client to Server from different networks ?
The IP range 172.16.0.0 to 172.31.255.255 is a private address space for use in local area networks. IPs from that range are only valid in the same private LAN.
When you deploy your server software on a host on the Internet which is outside of your local area network, you need to replace it with the IP address of that host. I never used AWS, but the first place I would be looking for when I would want to know the public IP address of a server I rent, would be the web-based control panel. When you have shell access to the server, you can also find it out with ipconfig on Windows and ifconfig on Unix.
Related
I'm creating two program files (one client one server).
Each file has one thread (one thread for server, one thread for client)
At runtime, there is supposed to be only one server, and there is supposed to be multiple and/or potentially infinite number of clients connecting to the server at the same time)
In order to get multiple clients to run, the user opens multiple command prompt / mac terminal windows (each window being one client) (one window being the server, so it requires at least two windows to run)
Once a client is connected, it can send messages (utf-8 strings) to the server. It will also receive from the server all messages sent from the other connected clients (it will not receive messages sent from itself).
The port number I am using to connect is 5344 (localhost).
Screenshot of client error:
Screenshot of server (no errors):
The error message is:
Exception in thread “Thread-75562” java.lang.NullPointerException at ChatClient$1.run(ChatClient.java:39)
The "39" is the line of code (I think) that the error is pointing at.
Screenshot of line 39 in ChatClient.java:
I have notice that some people use
Socket socket = new Socket(host, portNumber);
without calling any Socket.connect(host, portNumber); to connect to a server.
Does socket.connect() ever need to be used to connect a client to a server?
Code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatClient
{
private static Socket Socket;
static int numberOfClients = 0;
public static void main(String args[])
{
//If I wanted to create multiple clients, would this code go here? OR should the new thread creation be outside the while(true) loop?
while (true)
{
String host = "localhost";
int numberOfClients = 0;
Thread ChatClient1 = new Thread ()
{
public void run()
{
try
{
//Client begins, gets port number, listens, connects, prints out messages from other clients
int port = 0;
int port_1number1 = 0;
int numberofmessages = 0;
String[] messagessentbyotherclients = null;
System.out.println("Try block begins..");
System.out.println("Chat client is running");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
if(args.length>0)
{
port = Integer.valueOf(port_number1);
}
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
try
{
Socket.connect(null);
}
catch (IOException e1)
{
e1.printStackTrace();
}
System.out.println("Client has connected to the server");
boolean KeepRunning = true;
while(KeepRunning)
{
for(int i = 0; i < numberOfClients; i++)
{
System.out.println(messagessentbyotherclients);
}
try
{
//client creates new message from standard input
OutputStream os = Socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
}
catch (IOException e)
{
e.printStackTrace();
}
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input encoded in UTF-8 string format
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
input=null;
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
//Sending the message to server
String sendMessage = newmessage;
try
{
OutputStream os = Socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(sendMessage + "\n");
bw.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Message sent to server: "+sendMessage);
}
}
finally
{
}
}
};
ChatClient1.start();
}
}
}
Code of ChatServer.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatServer
{
private static Socket socket;
public static void main(String args[])
{
Thread ChatServer1 = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
int port_number1 = 0;
int numberOfClients = 0;
boolean KeepRunning = true;
if(args.length>0)
{
port_number1 = Integer.valueOf(args[0]);
}
System.out.println("Waiting for connections on port " + port_number1);
try
{
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
//create a list of clients
ArrayList<String> ListOfClients = new ArrayList<String>();
//connect to client
// socket = serverSocket.accept();
//add new client to the list, is this the right way to add a new client? or should it be in a for loop or something?
ListOfClients.add("new client");
numberOfClients += 1;
System.out.println("A client has connected. Waiting for message...");
ListOfClients.add("new client" + numberOfClients);
//reading encoded utf-8 message from client, decoding from utf-8 format
String MessageFromClientEncodedUTF8 = "";
BufferedReader BufReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String MessageFromClientDecodedFromUTF8 = BufReader1.readLine();
byte[] bytes = MessageFromClientEncodedUTF8.getBytes("UTF-8");
String MessageFromClientDecodedUTF8 = new String(bytes, "UTF-8");
//relaying message to every other client besides the one it was from
for (int i = 0; i < ListOfClients.size(); i++)
{
if(ListOfClients.get(i)!="new client")
{
String newmessage = null;
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (socket != null)
{
socket.close ();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
ChatServer1.start();
}
}
My question is: How to resolve the error and/or should I delete the socket.connect() while somehow still being able to connect to the server as a client?
I'm creating two program files (one client one server).
Each file has one thread (one thread for server, one thread for client)
At runtime, there is supposed to be only one server, and there is supposed to be multiple and/or potentially infinite number of clients connecting to the server at the same time)
In order to get multiple clients to run, the user opens multiple command prompt / mac terminal windows (each window being one client) (one window being the server, so it requires at least two windows to run)
Once a client is connected, it can send messages (utf-8 strings) to the server. It will also receive from the server all messages sent from the other connected clients (it will not receive messages sent from itself).
Screenshot of exception in thread / array index out of bounds error (eclipse):
Screenshot of Socket Exception error (server):
Screenshot of error on client side:
Code of Server (ChatServer.java):
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatServer
{
ChatServer chatserver = new ChatServer();
private static Socket socket;
public static void main(String args[])
{
Thread ChatServer1 = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
int port_number1 = 0;
int numberOfClients = 0;
boolean KeepRunning = true;
if(args.length>0)
{
port_number1 = Integer.valueOf(args[0]);
}
System.out.println("Waiting for connections on port " + port_number1);
try
{
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
//create a list of clients
ArrayList<String> ListOfClients = new ArrayList<String>();
//connect to client
// socket = serverSocket.accept();
//add new client to the list, is this the right way to add a new client? or should it be in a for loop or something?
ListOfClients.add("new client");
numberOfClients += 1;
System.out.println("A client has connected. Waiting for message...");
ListOfClients.add("new client" + numberOfClients);
//reading encoded utf-8 message from client, decoding from utf-8 format
String MessageFromClientEncodedUTF8 = "";
BufferedReader BufReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String MessageFromClientDecodedFromUTF8 = BufReader1.readLine();
byte[] bytes = MessageFromClientEncodedUTF8.getBytes("UTF-8");
String MessageFromClientDecodedUTF8 = new String(bytes, "UTF-8");
//relaying message to every other client besides the one it was from
for (int i = 0; i < ListOfClients.size(); i++)
{
if(ListOfClients.get(i)!="new client")
{
String newmessage = null;
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (socket != null)
{
socket.close ();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
ChatServer1.start();
}
}
Code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatClient
{
static int numberOfClients = 0;
public static void main(String args[])
{
ChatClient chatclient = new ChatClient();
//If I wanted to create multiple clients, would this code go here? OR should the new thread creation be outside the while(true) loop?
while (true)
{
String host = "localhost";
int numberOfClients = 0;
Thread ChatClient1 = new Thread ()
{
public void run()
{
try
{
//Client begins, gets port number, listens, connects, prints out messages from other clients
int port = 0;
int port_1number1 = 0;
int numberofmessages = 0;
String[] messagessentbyotherclients = null;
System.out.println("Try block begins..");
System.out.println("Chat client is running");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
if(args.length>0)
{
port = Integer.valueOf(port_number1);
}
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
boolean KeepRunning = true;
while(KeepRunning)
{
for(int i = 0; i < numberOfClients; i++)
{
System.out.println(messagessentbyotherclients);
}
try
{
Socket clientSocket = new Socket("localhost", port);
InetAddress inetlocalhost = InetAddress.getByName("localhost");
SocketAddress localhost = new InetSocketAddress(inetlocalhost, port);
clientSocket.connect(localhost, port);
System.out.println("Client has connected");
//client creates new message from standard input
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
}
catch (IOException e)
{
e.printStackTrace();
}
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input encoded in UTF-8 string format
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
input=null;
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
//Sending the message to server
String sendMessage = newmessage;
try
{
Socket clientSocket = new Socket("localhost", port);
SocketAddress localhost = null;
clientSocket.connect(localhost, port);
OutputStream os = clientSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(sendMessage + "\n");
bw.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("Message sent to server: "+sendMessage);
}
}
finally
{
}
}
};
ChatClient1.start();
}
}
}
My question is: How should I go about resolving all three errors (it seems like if I change one part of the code, then the other errors will either still exist or be resolved due to that but I could be wrong)? I would also like to know if there's a way to list the number of clients in an arraylist in the server code so that when a client closes their window I can keep the server up by just removing them from the list.
I want to write a socket client to send a request to a server and get response back. It works, but not right.
Here is my code:
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.error(e);
this.log.error("Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.error("Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if (StringUtils.isBlank(response)) return null;
return response;
}
The problem is: I didn't got the full response with in.readUTF(). I always got a response with the same length as the sent data's length (variable data). I have tested with other GUI client and got the full response. So it's not a problem of the server.
Does someone known, what i did wrong?
UPDATE
Thanks EJP and Andrey Lebedenko. I think, my problems are the functions writeUTF and readUTF. So i have edited my code in the try block so:
Charset charset = Charset.forName("ISO-8859-1");
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.write(data.getBytes(charset));
final InputStream inFromServer = client.getInputStream();
final BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, charset));
response = in.readLine();
And it worked now.
If it works with Telnet, as per your comment, the server isn't using readUTF(), so your writeUTF() is already wrong, and the server is therefore unlikely to be using writeUTF() either, which would make your readUTF() wrong as well. You can't use these methods arbitrarily: they can only interchange data between themselves.
I'll bet your GUI client that works doesn't use them either.
Without knowing what does server part do, it is kind of difficult (if possible at all) to trace down the root cause. So in the most honest hope that it will help I just share this code with which I've tested the fragment above.
package tcpsendreceive;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SendReceive {
private static final Logger log = Logger.getLogger(SendReceive.class.toString());
private final String host;
private final int port;
private Server server;
class Server extends Thread
{
private final ServerSocket serverSocket;
public Server(ServerSocket s)
{
serverSocket = s;
}
#Override
public void run()
{
Socket connection;
SendReceive.this.log.log(Level.INFO, "Server: DoubleEcho Server running on "+this.serverSocket.getLocalPort());
try{
do {
connection = this.serverSocket.accept();
SendReceive.this.log.log(Level.INFO, "Server: new connection from "+connection.getRemoteSocketAddress());
int b;
do {
DataInputStream in = new DataInputStream(connection.getInputStream());
String s = in.readUTF();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeUTF(s+","+s); // echo it back TWICE
out.flush();
connection.shutdownOutput();
connection.close();
} while(!connection.isClosed());
}
while(true);
}
catch(IOException ioe)
{
SendReceive.this.log.log(Level.SEVERE, "IOException in server! - STOP", ioe);
}
finally {
try{
this.serverSocket.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
try{
if(!connection.isClosed())
connection.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
}
}
}
public SendReceive(String host, int port)
{
this.host = host;
this.port = port;
try{
this.server = new Server(new ServerSocket(this.port));
this.server.start();
}
catch(IOException ioe)
{
this.log.log(Level.SEVERE, "IOException while creating server! - STOP", ioe);
}
}
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if(response == null || response.isEmpty())
return null;
return response;
}
}
Test-demo
package tcpsendreceive;
public class Main {
public static void main(String[] args)
{
String data = "AAABBB";
SendReceive sr = new SendReceive("localhost", 5000);
String res = sr.send(data);
System.out.println("Sent: "+data);
System.out.println("Received: "+res);
}
}
Result (key part):
Sent: AAABBB
Received: AAABBB,AAABBB
Hope it helps.
EDIT
1. Corrected wrapper flush instead of socket stream flush. Still believe it is good practice to flush the stream wrapper before closing the socket.
Client socket closed in IOException block (since they aren't automatically closed on ServerSocket shutdown). Thanks #EJP
P.s. I should admit I was bit surprised by such an attention to the humble test server code, especially compared to other dirty tests we all have seen on SO. Flattered. :)
The code below should allow the user to enter a URL and have it return the ip address of that website but it's not working.
The application is a console application. I had it working at one time but I don't know why it won't work now.
Here is the error i am getting when the users enters a website to get the ip address from
IOException: java.net.SocketException: Connection reset
HERE IS MY CLIENT CODE
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
String hostname = "localhost";
int port = 6052;
if (args.length > 0) {
hostname = args[0];
}
Socket clientSocket = null;
PrintWriter os = null;
BufferedReader is = null;
try {
clientSocket = new Socket(hostname, port);
os = new PrintWriter(clientSocket.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + hostname);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + hostname);
}
if (clientSocket == null || os == null || is == null) {
System.err.println("Something is really wrong. ");
return;
}
try {
if (args.length != 2) {
System.out.print("Enter a www web address (must have www!) ");
BufferedReader br = new BufferedReader(new InputSreamReader(Sy.in))
String keyboardInput = br.readLine();
os.println(keyboardInput);
} else {
os.println(args[1]);
}
String responseLine = is.readLine();
System.out.println("The IP address of " + args[1] + "is" + responseLine);
} catch (UnknownHostException e) {
System.err.println("Trying to connect to host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
HERE IS MY SERVER CODE
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) {
int port = 6052;
Server server = new Server(port);
server.startServer();
}
ServerSocket echoServer = null;
Socket clientSocket = null;
int numConnections = 0;
int port;
public Server(int port) {
this.port = port;
}
public void stopServer() {
System.out.println("Server working hold on a min.");
System.exit(0);
}
public void startServer() {
try {
echoServer = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server is now started and is waiting for Clients.");
while (true) {
try {
clientSocket = echoServer.accept();
numConnections++;
new Thread(new ServerConnection(clientSocket, numConnections,
this)).start();
} catch (IOException e) {
System.out.println(e);
}
}
}
}
class ServerConnection implements Runnable {
private static BufferedReader is;
private static PrintStream os;
private static Socket clientSocket;
private static int id;
private static Server server;
public ServerConnection(Socket clientSocket, int id, Server server) {
this.clientSocket = clientSocket;
this.id = id;
this.server = server;
System.out.println( "Connection " + id + " established with: " + clientSocket );
try {
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public void run() {
String line;
try {
boolean serverStop = false;
line = is.readLine();
System.out.println( "Received " + line + " from Connection " + id + "." );
InetAddress hostAddress = InetAddress.getByName(line);
String IPaddress = hostAddress.getHostAddress();
os.println(IPaddress);
is.close();
os.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
With no arguments, host will be localhost, user will be propted for a website. ArrayOutOfBoundsException because you didn't check the arguments.
With one argument, it is the host. Passing a site will not work because the site won't work as expected.
Running with two arguments, it works if the first argument is localhost.
I have a client class and a server class.
If client sends message to server, server will send response back to the client, then client will print all the messages it received.
For example,
If Client sends "A" to Server, then Server will send response to client
"1111". So I use readLine() in client class to read the message from server, then client print "1111" in the console.
If Client sends "B" to Server, then Server will send response to client
"2222\n 3333". So the expected printing output from client is:
"2222"
"3333"
So the response message from server to client may have 1 line or 2 lines depending on the message it send from client to server.
My question is that how I can use readLine() to read the message that send from server to client. More specifically, if I use the following codes,
String messageFromServer;
while(( messageFromServer = inputStreamFromServer.readLine()) != null) {
println(messageFromServer);
}
It will only print the first line, and will not print anything else even if I keep sending message from client to server, because readLine() will stops once it has read the first line.
update:
More specifically, I am looking for some methods in the client class to read message that contains 1 or multiple lines from server at a time. I am wondering if there are any ways to do it in client side if I don't want to change the format of the message that sent from server to client.
update 2
To make my question more clear, I will put some sample codes in the following:
This is server:
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(1234);
} catch (IOException e) {
System.err.println("Could not listen on port: 1234.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
}
System.out.println("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient =null;
String textToClient =null;
textFromClient = in.readLine(); // read the text from client
if( textFromClient.equals("A")){
textToClient = "1111";
}else if ( textFromClient.equals("B")){
textToClient = "2222\r\n3333";
}
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
The client:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try {
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection");
}
System.out.println("Connected");
String textToServer;
while((textToServer = read.readLine())!=null){
out.print(textToServer + "\r\n" ); // send to server
out.flush();
String messageFromServer =null;
while(( messageFromServer = textToServer=in.readLine()) != null){
System.out.println(messageFromServer);
}
}
out.close();
in.close();
read.close();
socket.close();
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
You shouldn't need to change the format of the data sent by the server, and readLine() should work, but I suspect that the server is not flushing or closing the OutputStream after writing the response which could possibly explain things.
Is the call to readLine() hanging? Are you in control of the server code? If so, can you include it?
Revised classes that work as I believe you expect:
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 ClientServerTest2
{
public static void main(String[] args) throws Exception
{
Thread serverThread = new Thread(new Server());
serverThread.start();
Thread clientThread = new Thread(new Client());
clientThread.start();
serverThread.join();
clientThread.join();
}
private static class Server implements Runnable
{
#Override
public void run()
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(1234);
Socket clientSocket = null;
clientSocket = serverSocket.accept();
debug("Connected");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String textFromClient = null;
String textToClient = null;
textFromClient = in.readLine(); // read the text from client
debug("Read '" + textFromClient + "'");
if ("A".equals(textFromClient))
{
textToClient = "1111";
}
else if ("B".equals(textFromClient))
{
textToClient = "2222\r\n3333";
}
debug("Writing '" + textToClient + "'");
out.print(textToClient + "\r\n"); // send the response to client
out.flush();
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void debug(String msg)
{
System.out.println("Server: " + msg);
}
}
private static class Client implements Runnable
{
#Override
public void run()
{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
try
{
socket = new Socket("localhost", 1234);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
debug("Connected");
String textToServer;
textToServer = read.readLine();
debug("Sending '" + textToServer + "'");
out.print(textToServer + "\r\n"); // send to server
out.flush();
String serverResponse = null;
while ((serverResponse = in.readLine()) != null)
debug(serverResponse); // read from server and print it.
out.close();
in.close();
read.close();
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private static void debug(String msg)
{
System.out.println("Client: " + msg);
}
}
Change while(( messageFromServer = inputStreamFromServer.readLine() != null) to while(( messageFromServer = inputStreamFromServer.readLine()) != null)
Actually this shouldn't even compile....
It's a work around.
If you want to send multiple strings like in your case : "2222\n 3333".
You can send them by adding a seperator character (like :) between two strings : "2222: 3333".
Then you can call write from server side as
clientOut.write("2222: 3333\n");
On client side parse recieved String :
messageFromServer = inputStreamFromServer.readLine();
String strArray[] = messageFromServer.split(":");
strArray[0] : 2222
strArray[0] : 3333