I have the two programs and i want them to connect to my school server afs1.njit.edu but it never connects. That is where i have the files. should i run two ssh programs to each run the different programs? unsure how to test them. (these are a simple ezxample from online i want to test before i write my code) I compile them serperately and they never connect.
singleSocketserver.java
public static void main(String[] args) {
try{
socket1 = new ServerSocket(port);
System.out.println("SingleSocketServer Initialized");
int character;
while (true) {
connection = socket1.accept();
BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
InputStreamReader isr = new InputStreamReader(is);
process = new StringBuffer();
while((character = isr.read()) != 13) {
process.append((char)character);
}
System.out.println(process);
//need to wait 10 seconds for the app to update database
try {
Thread.sleep(10000);
}
catch (Exception e){}
TimeStamp = new java.util.Date().toString();
String returnCode = "SingleSocketServer repsonded at "+ TimeStamp + (char) 13;
BufferedOutputStream os = new BufferedOutputStream(connection.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write(returnCode);
osw.flush();
}
}
catch (IOException e) {}
try {
connection.close();
}
catch (IOException e) {}
}
}
SocketClient.java
public class SocketClient {
public static void main(String[] args) {
/** Define a host server */
String host = "afs1.njit.edu";
/** Define a port */
int port = 19999;
StringBuffer instr = new StringBuffer();
String TimeStamp;
System.out.println("SocketClient initialized");
try {
/** Obtain an address object of the server */
InetAddress address = InetAddress.getByName(host);
/** Establish a socket connetion */
Socket connection = new Socket(address, port);
/** Instantiate a BufferedOutputStream object */
BufferedOutputStream bos = new BufferedOutputStream(connection.
getOutputStream());
/** Instantiate an OutputStreamWriter object with the optional character
* encoding.
*/
OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");
TimeStamp = new java.util.Date().toString();
String process = "Calling the Socket Server on "+ host + " port " + port +
" at " + TimeStamp + (char) 13;
/** Write across the socket connection and flush the buffer */
osw.write(process);
osw.flush();
/** Instantiate a BufferedInputStream object for reading
/** Instantiate a BufferedInputStream object for reading
* incoming socket streams.
*/
BufferedInputStream bis = new BufferedInputStream(connection.
getInputStream());
/**Instantiate an InputStreamReader with the optional
* character encoding.
*/
InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");
/**Read the socket's InputStream and append to a StringBuffer */
int c;
while ( (c = isr.read()) != 13)
instr.append( (char) c);
/** Close the socket connection. */
connection.close();
System.out.println(instr);
}
catch (IOException f) {
System.out.println("IOException: " + f);
}
catch (Exception g) {
System.out.println("Exception: " + g);
}
}
}
if you're trying to connect from your home to the school's computer, then you will likely hit a firewall. Usually, though not always, connections initiated from the machine are allowed, but connections to the machine are only allowed on certain ports. You can set up your ssh to tunnel the packets but then you may as well run the 2 programs next to one another.
If you run both programs on the same machine, they should find one another, assuming that:
1: you are allowed to open sockets
2: the socket isn't already taken by anothe program
3: the firewall doesn't block those ports.
to run both on the school machine you can use 2 shells (ssh) but it isn't necessary. you can run the receiver in the background (put a & at the end of the command) and then run the sender. However it is easier to run 2 shells, especially if the program sends to sysout like yours does.
a few pointers, if you use System.out (or System.err) for debug / log output, when you consume an exception, I recommend e.printStackTrace(System.out) if you don't want to pull in a library for this. Most logging frameworks have a logger.error("message", ex) and commons.lang has an exception printer too.
How can I convert a stack trace to a string?
One thing you can do to test your logic, without the socket connection, is to use PipedInputStream and PipedOutputStream. http://docs.oracle.com/javase/7/docs/api/java/io/PipedInputStream.html but if you're sure of your logic and need to test sockets you'll have to run them side by side.
Related
I'm looking for a way to establish an HTTP Request via java to ensure the server is alive.
for example I want to scan ip addresses range 192.168.1.1-255 and print a log with the living server.,
I want to setTimeOut for 3Seconds when the HTTP response is delayed for some reason.
I have tried to do it this way:
try {
Socket s = new Socket(InetAddress.getByName("192.168.1.2"), 80);
s.setSoTimeout(3 * 1000);
PrintWriter pw = new PrintWriter(s.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: stackoverflow.com");
pw.println("");
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while ((t = br.readLine()) != null) System.out.println(t);
br.close();
} catch (SocketTimeoutException e) {
System.out.println("Server is dead.");
} catch (ConnectException e) {
System.out.println("Server is dead.");
}
But it's seem to be not waiting at all when the request is taking longer than 3000millis.
Thanks!
I think you confused the different timeouts. If you want to abort the connection attempt after three seconds without any response, then you should establish the connection as follows:
Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);
where target is any IP address. The following line essentially set the timeout value for reading/waiting for the inputstream -after the connection was established. So it has not effect on establishing the connection itself. However, after the connection was established it would interrupt the "read inputstream" step after three seconds (by throwing an exception).
clientSocket.setSoTimeout(3 * 1000);
However, if you want to limit also the time for reading the inputstream without throwing an exception, then you need a costum solution:
Is it possible to read from a InputStream with a timeout?
The following running example worked very well in my local network. It tried to connect for at most three seconds and detected all running webservers.
public class Main {
public static void main(String[] args) {
String net = "192.168.168."; // this is my local network
for (int i = 1; i < 255; i++) { // we scan the range 1-255
String target = net + i;
System.out.println("Try to connect to: " + target);
try {
Socket clientSocket = new Socket();
// we try to establish a connection, timeout is three seconds
clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);
// talk to the server
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.println("GET / HTTP/1.1");
out.println("Host: stackoverflow.com");
out.println("");
out.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String t;
while ((t = br.readLine()) != null) System.out.println(t); // We print the answer of the server
br.close();
clientSocket.close();
// server seems to be alive
System.out.println("> Server is alive");
} catch (SocketTimeoutException | ConnectException e) {
System.out.println("> Server is dead");
} catch (Exception e) { // This is not nice but this is also just a demo
e.printStackTrace();
}
}
}
}
Output (excerpt):
Try to connect to: 192.168.168.1
> Server is dead
Try to connect to: 192.168.168.2
> Server is dead
...
Try to connect to: 192.168.168.23
(answer of the server)
> Server is alive
...
I am currently working on a Java console application. It is run through the command prompt, connects to a server application coded in python and communicates with that server over TCP. My application sends "ISND" string to server which it accepts and in return server sends three images. The format in which Images are sent in is
Where "<"">" are not actually included. "ISND" is encoded into bytes using ascii. Size is the size of the image converted into bytes from int and it is always composed of 3 bytes regardless of the size of the image. For each individual image, a message in this format is sent.
I have been using BufferedReader to read server responses but at this point, I am at a loss on how to actually handle this message. I searched for ways to separate the incoming message into components since I know the length of the first two parts which are always fixed yet I couldn't find a way to actually accomplish that goal.
It has come to the point it feels like I am smashing my head into a wall. As such, I need advice from anyone that is more familiar with Java and Socket programming on how to handle this issue.
My current code
public class ImageLabeler {
/**
* #param args
*/
public static void main(String[] args) {
String IP = args[0];
System.out.println(IP + "\n");
String port = args[1];
System.out.println(port + "\n");
Socket clientSocket;
DataOutputStream outToServer = null;
BufferedReader inFromServer = null;
String serverResponse;
try {
clientSocket = new Socket(IP, Integer.parseInt(port));
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Connection success\n");
} catch (IOException ex) {
System.out.println("Connection failed\n");
System.exit(0);
}
PrintWriter writer = new PrintWriter(outToServer, true);
try {
//outToServer.writeBytes("USER bilkentstu\\n");
//outToServer.flush();
//System.out.println("check\n");
writer.println("USER bilkentstu");
serverResponse = inFromServer.readLine();
System.out.println(serverResponse + "\n");
writer.println("PASS cs421f2019");
//outToServer.writeBytes("PASS cs421f2019\\r\\n");
//outToServer.flush();
serverResponse = inFromServer.readLine();
System.out.println(serverResponse + "\n");
writer.println("IGET");
//This is where I need to handle the incoming Image messages.
writer.println("EXIT");
} catch (IOException ex) {
Logger.getLogger(ImageLabeler.class.getName()).log(Level.SEVERE, null, ex);
}
System.exit(0);
}
}
Don't use buffered reader. You need to write the code reading a string from the InputStream of the socket one byte at a time.
I have this funny behavior in debug mode which I can't explain to myself.
There are two small client and server applications, and the flow goes like this:
Client initiates TCP connection
Server accepts and sends message to client requesting packet data size(it's fixed)
Client sends the size
Server reads the size and initializes some byte array - this works
Server blocks on read() from the input stream waiting on packets and client sends packets. - this is culprit
It all works when i run the applications, however when I debug the Server - it simply blocks on read().
If i send more than one message, for example 50, the Server receives 49 of those. Once client closes connection, Server reads -1 from stream and exits, with the first message lost.
The only thing i can think of is that in debug mode, client sends message before server reads it from stream but i don't see how could that be relevant as the message should be there.
Could somebody explain this behavior i am experiencing in debug mode only?
Note: client code is there just for debug, so it's not the prettiest.
Server
private static int sent;
public void processClientInput(HealthCheckSession session) {
byte[] buffer = session.getBuffer();
DataInputStream stream = session.getInFromClient();
int readBytes = 0;
int totalBytes = 0;
try {
while((readBytes = stream.read(buffer)) !=-1) { <---- this blocks in debug on first message
totalBytes += readBytes;
if (totalBytes < buffer.length) {
continue;
}
else {
totalBytes = 0;
String packet = new String(buffer, ProtocolValidator.SERIALIZATION_CHARSET);
sendResponse(packet);
}
}
} catch (IOException e) {e.printStackTrace();}
}
private void sendResponse(String packet) {
System.out.println(packet);
++sent;
System.out.println("sent " + sent);
}
Client
public static void main(String[] args) throws UnknownHostException,
IOException, InterruptedException {
Socket clientSocket = new Socket("localhost", 10002);
// get the socket's output stream and open a PrintWriter on it
PrintWriter outToServer = new PrintWriter(
clientSocket.getOutputStream(), true);
// get the socket's input stream and open a BufferedReader on it
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
System.out.println("before read");
System.out.println(inFromServer.readLine());
System.out.println("after read");
byte[] packageData = "100, ABCDZEGHR"
.getBytes(Charset.forName("UTF-8"));
String size = String.valueOf(packageData.length);
outToServer.println(size);
for (int i = 0; i < 50; i++) {
DataOutputStream dis = new DataOutputStream(
clientSocket.getOutputStream());
System.out.println("before write");
dis.write(packageData);
dis.flush();
System.out.println("after write");
Thread.sleep(1000);
}
try {
Thread.sleep(100 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clientSocket.close();
}
IMPORTANT UPDATE
This does not happen in Netbeans debug mode.
I'm writing a simple server in Java, and I'm able to retrieve incoming data from the client on the server side, but not on the client side due to a 2000ms timeout. Anyone know why this times out?
This is the server's code:
private static void listen() throws IOException {
while(true) {
Socket clientSocket = serverSocket.accept();
StringBuilder bufferedStringInput = new StringBuilder();
CharBuffer cbuf = CharBuffer.allocate(4096);
try {
InputStream is = clientSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF8"));
int noCharsLeft = 0;
while ((noCharsLeft = br.read(cbuf)) != -1) {
char[] arr = new char[noCharsLeft];
cbuf.rewind();
cbuf.get(arr);
bufferedStringInput.append(arr);
cbuf.clear();
}
System.out.println(bufferedStringInput.toString());
} catch (IOException e) {
System.out.println("Error received client data: " + e.getMessage());
}
String message = "Hello client";
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.print(message);
} catch (IOException e) {
System.out.println("Error getting output stream from client: " + e.getMessage());
}
clientSocket.close();
}
}
You're reading the input until end of stream, which only happens when the peer closes the connection, then you're trying to write to it, so of course you get a broken pipe. Doesn't make sense. You should just read the input until you have one entire request, whatever that means in your protocol.
There are other problems lurking here:
If the client code uses readLine(), you're not sending a line terminator: use println(), not print(), and close the PrintWriter, not just the client socket.
cbuf.rewind()/get()/clear() should be cbuf.flip()/get()/compact().
But it would make more sense to read directly into a char[] cbuf = new char[8192]; array, then bufferedStringInput.append(cbuf, 0, noCharsLeft), and forget about the CharBuffer altogether. Too much data copying at present.
noCharsLeft is a poor name for that variable. It is a read count.
I have a Java program that mirrors a connection from a client server to a remote server. The mirror send data find, but does not receive. I cannot for the life of me figure out why. Here is my code:
Socket client = new Socket("127.0.0.1", 42001);
System.out.println("Connected to client!");
Socket server = new Socket(serverAddress, serverPort);
System.out.println("Connected to server!");
BufferedReader clientin = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter scratchout = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader serverin = new BufferedReader(new InputStreamReader(server.getInputStream()));
BufferedWriter serverout = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
int i;
boolean serverNeedsFlush = false;
boolean clientNeedsFlush = false;
while (true)
{
while (clientin.ready())
{
i = clientin.read();
serverout.write(i);
serverNeedsFlush = true;
}
if(serverNeedsFlush)
{
serverout.flush();
serverNeedsFlush = false;
}
while (serverin.ready())
{
i = serverin.read();
System.out.print((char)i);
scratchout.write(i);
clientNeedsFlush = true;
}
if(clientNeedsFlush)
{
scratchout.flush();
clientNeedsFlush = false;
}
}
If your trying to forward data from one socket to another it would probably be a better idea to use the socket streams directly rather than decorating them.
As other posters have suggested you should use threads to do this. It will make life easier. You can then use the threads to do a basic in to out stream copy like below.
public static void streamCopy(InputStream in, OutputStream out)
throws IOException{
byte[] data = new byte[1024];
int length;
do{
length = in.read(data);
if(length > 0){
out.write(data, 0, length);
out.flush();
}
}while(length != -1);
}
When the method above returns you will have read the entire in stream and written it in to the out stream. Your run method for your thread or runnable could look something like this.
public void run() {
Socket inSock = null;
Socket outSock = null;
try{
inSock = new Socket(inHost, inPort);
outSock = new Socket(inHost, inPort);
/* Set up some socket options here (timeouts, buffers etc)*/
/* Insert pre copy actions */
/* This method won't return until inSock's inputStream hits end of stream.
* and all the data has been written to outSock's outputStream and flushed. */
streamCopy(inSock.getInputStream(), outSock.getOutputStream());
/* In order to really do this correctly you should create an
* application protocol that verifies the upstream receiver
* is actually getting the data before you close the socket. */
/* Insert post copy actions */
}catch(Exception e){
/* Corrective action or logging here */
}finally{
/* Don't forget to close the sockets. */
if(inSock != null){
try{
inSock.close();
}catch(Exception e){
/* Don't care */
}
}
if(outSock != null){
try{
outSock.close();
}catch(Exception e){
/* Don't care */
}
}
}
}
You can't do this properly in one thread. You need two threads, one in each direction. Each thread just reads and writes until it encounters EOS. And don't use available(): just block in the read. Set a read timeout to avoid pathological situations.