Is there anyway to set a timeout for a client socket if the client don't get/send any message in a certain time?
here is a sniplet of my code :
try {
mainSocket = new ServerSocket(portNumber);
clientSocket = mainSocket.accept();
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
} catch (IOException ex) {
Logger.error(this, "failed to accept connection. Error was " + ex.getMessage());
}
while (reading) {
try {
char[] arr = new char[2048];
ch = 0;
ch = in.read(arr);
if (ch < 0) {
reading = false;
}
else {
//process message
} catch (IOException ex) {
Logger.error(this, ex);
}
}
now what I want to do is if after x second the clientSocket didn't get any message, it will exit the loop, close the connection and restart accepting connection.
I know how to close the connection and restart accepting connection, but I still can't figure the rest. Is there anyway to accomplish this?
Thanks for the help
Related
I'm trying to send and read the reply from the socket with no luck. What I got so far is, connected to the server and read connection reply (header from Ericsson telco exchange) and printed it on System.out. What I need to be able to do is send a command to the exchange and get the reply and that's where I'm stuck. Below is my test code.
Any help is appreciated.
public class ExchangeClientSocket {
public void run() {
try {
int serverPort = 23;
InetAddress host = InetAddress.getByName("my.host.ip.address");
Socket socket = new Socket(host, serverPort);
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(isr);
int i;
StringBuffer buffer = new StringBuffer();
while (true) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
// this returns the head from exchange
System.out.println(buffer.toString());
out.write("allip;"); // command I want to send to exchange
out.flush();
System.out.println(in.ready()); // this returns false
System.out.println(in.read());
System.out.println("damn..");
buffer = new StringBuffer();
// can't get into this loop
// this is where I want to read the allip response
while ((i = in.read()) != -1) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
System.out.println(buffer.toString());
out.close();
in.close();
socket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is a suggestion on how to get input from the server after writing to the output stream: simply get another input stream from the socket.
So instead of reading from the same stream you create a new stream from the socket after you sent the command and read it.
I would therefore suggest to change your code to this here:
public void run() {
try {
int serverPort = 23;
InetAddress host = InetAddress.getByName("my.host.ip.address");
Socket socket = new Socket(host, serverPort);
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(isr);
int i;
StringBuffer buffer = new StringBuffer();
while (true) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
// this returns the head from exchange
System.out.println(buffer.toString());
out.write("allip;"); // command I want to send to exchange
out.flush();
// Create a new input stream here !!!
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
buffer = new StringBuffer();
// can't get into this loop
while ((i = in.read()) != -1) {
i = in.read();
if (i == 60) {
break;
} else {
buffer.append((char) i);
}
}
System.out.println(buffer.toString());
out.close();
in.close();
socket.close();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have followed some tutorials to create a basic server that can handle multiple clients at once. It receives data correctly but it chews up more and more memory until it runs out of heap space. I believe it is because my loop is not recognising my end character and leaving the for loop.
Here is the code for the thread which receives the data:
while (true){
try {
is = new BufferedInputStream(s.getInputStream());
InputStreamReader isr = new InputStreamReader(is);
int character;
StringBuilder process = new StringBuilder();
try {
while((character = isr.read()) != 13) {
process.append((char)character); //here is the issue - it just continues to append until it runs out of memory
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
parent.parent.writeToLog("Client " + Integer.toString(num) + " sent a message: " + process.toString());
System.out.println(process);
is = null;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedOutputStream os;
try {
os = new BufferedOutputStream(s.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write("Response from server at client socket " + Integer.toString(num) + " at " + (new java.util.Date()).toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I've put a comment into the code where it shows me the error on the stack trace. Here is the client, which is just the EchoClient from the Java tutorials:
import java.io.*;
import java.net.*;
import java.util.Random;
public class EchoClient {
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("localhost", 2405);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
out.println("Message to host: hello" + (char) 13);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println(Integer.toString((new Random()).nextInt()) + (char) 13);
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
You can see where I append the character 13 to the output and that is what is meant to end the loop but from my understanding this is not working. Could anyone help me out with this?
I think the problem lies in the following code:
while((character = isr.read()) != 13) {
process.append((char)character); //here is the issue - it just continues to append until it runs out of memory
}
Even when end of stream is reached isr.read() would return -1 and not 13. There's a possibility that you are never receiving input character that is 13 to exit out of the loop.
This is likely the problem: while((character = isr.read()) != 13)
Why are you checking for 13? InputStreamReader.read() will return -1 if the end of the stream is reached.
My guess is that you're hitting the end of the stream and filling your StringBuilder with garbage. Note that (char)-1 actually represents the unicode character 65535.
I am sending lines through a socket from a client in C, and reading on a server in Java. The best I can manage is that the client send the multiple lines, and when I close the client the server prints all the data in one line. Or to make it that one send then receives, etc. My desire is that the C application sends "Hi" in a loop, and the Java files catches first hi, prints and then catches second and prints. Right now it prints "HiHiHiHi...", but only when the connection is terminated.
I am using oracle socket example as guideline and using another guide for the C client
So reading the socket in Java is:
try {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println("Connected with client");
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("RECEIVING " + inputLine);
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
} finally {
out.close();
}
Trying to write to the socket in a while loop the same string in C:
void connection(void) {
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
/* Set time limit. */
timeout.tv_sec = 0;
timeout.tv_usec = 10;
portno = 4444;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname("Localhost");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
while(1) {
/* Create a descriptor set containing our two sockets. */
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
if (rc==-1) {
perror("select failed");
}
bzero(buffer,256);
char *buffer2 = "here";
n = write(sockfd,buffer2,strlen(buffer2));
if (n < 0)
error("ERROR writing to socket");
}
}
Your server is waiting for a \n before it prints anything.
Your client isn't sending any \n chars.
You might try:
char *buffer2 = "here"\n;
Below are my server and client authentication program. I was wondering am I doing it in the correct way, I want the message being send and receive in order which mean, the server only send the data after receiving the input from client, same thing goes to client, after receiving the response from server then replying.
Client class:
try {
// Set up the socket
connection = new Socket("127.0.0.1", 55555);
PrintWriter out = new PrintWriter(connection.getOutputStream(),
true);
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
// Client --> Server 'A'
BigInteger A = client.Step1(username, password);
out.println(A);
// Client received s , B
byte[] s = new BigInteger(in.readLine()).toByteArray();
BigInteger B = new BigInteger(in.readLine());
// Client --> Server 'A'
BigInteger M1 = client.Step2(new BigInteger(s), B);
out.println(M1);
// Client received M2
BigInteger M2 = new BigInteger(in.readLine());
boolean clientVerify = client.clientVerify(M2);
if (clientVerify) {
System.out.println("Client OK");
} else {
System.out.println("NOT OK");
}
out.close();
in.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
Server class:
try {
socServer = new ServerSocket(55555);
System.out.println("Waiting Client....");
connection = socServer.accept();
System.out.println("Client Connected");
PrintWriter out = new PrintWriter(connection.getOutputStream(),
true);
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
// Server received A
BigInteger A = new BigInteger(in.readLine());
// Server --> Client 's' , 'B'
out.println(new BigInteger(s));
BigInteger B = server.step1(username, new BigInteger(s), v);
out.println(B);
server.step2(A);
// Server received 'M1'
BigInteger M1 = new BigInteger(in.readLine());
boolean serverVerify = server.serverVerify(M1);
if (serverVerify) {
// Server --> Client 'M2'
BigInteger M2 = server.step2(A, M1);
out.println(M2);
System.out.println("Server OK");
} else {
System.out.println("NOT OK");
connection.close();
}
out.close();
in.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
Am I able to capture the data through Wireshark?
I'm trying to get a live flash that lives on a webserver to talk to a local java server, that will live on the clients PC.
I'm trying to achieve this with a socket connection. (port 6000)
Now, at first flash was able to connect, but it just sends <policy-file-request/>. After this nothing happens.
Now, some people at Kirupa suggested to send an cross-domain-policy xml as soon as any connection is established from the java side. http://www.kirupa.com/forum/showthread.php?t=301625
However, my java server just throws the following:
End Exception: java.net.SocketException: Software caused connection abort: recv failed
I've already spend a great amount of time on this subject, and was wondering if anyone here knows what to do?
I found the anwser, So ill post it here in case someone with a simmilar question finds this post.
The moment Flash connects to a local socket server it will send the following:
<policy-file-request/>
We will have to answer with a policy file and immediatly close the connection.
Java:
import java.net.*;
import java.io.*;
public class NetTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;
/* Open a socket to listen */
try {
serverSocket = new ServerSocket(6000);
} catch (IOException e) {
System.out.println("Could not listen on port: 6000");
System.exit(-1);
}
// Try catch a socket to listen on
Socket clientSocket = null;
try {
System.out.println("Waiting for auth on 6000...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
InputStream in = null;
OutputStream out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket connection incoming!");
// Keep going while we can...
byte b[] = new byte[100];
int offset = 0;
String s;
try {
boolean done = false;
boolean auth = false;
String protocol_target = "<policy-file-request/>";
byte[] p_bytes = protocol_target.getBytes();
int result;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
if (!auth) {
++offset;
b[offset] = 0;
if (offset != p_bytes.length) {
System.out.println("Waiting for protocol data... ("
+ offset + "/" + p_bytes.length + ")");
} else {
// Compare byte data
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(b[i] + " ");
}
System.out.print("\n");
System.out.flush();
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(p_bytes[i] + " ");
}
System.out.print("\n");
System.out.flush();
boolean match = true;
for (int i = 0; i < p_bytes.length; ++i) {
if (b[i] != p_bytes[i]) {
match = false;
System.out
.println("Mismatch on " + i + ".");
}
}
if (match)
auth = true;
else {
System.out.println("Bad protocol input.");
System.exit(-1);
}
}
// Auth
if (auth) {
System.out.println("Authing...");
s = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain='*' to-ports='6000' /></cross-domain-policy>";
b = s.getBytes();
out.write(b, 0, b.length);
b[0] = 0;
out.write(b, 0, 1); // End
out.flush();
offset = 0;
b = new byte[100];
b[0] = 0;
auth = true;
System.out.println("Auth completed.");
}
}
}
}
} catch (IOException e) {
System.out.println("Stream failure: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
} catch (Exception e) {
System.out.println("Failed closing auth stream: " + e.getMessage());
System.exit(-1);
}
// Try catch a socket to listen on for data
try {
System.out.println("Waiting on 6000 fo data...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
in = null;
out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket data connection waiting.");
// Echo
try {
boolean done = false;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
b[1] = 0;
s = new String(b);
System.out.print(s);
System.out.flush();
}
}
} catch (IOException e) {
System.out.println("Failed echo stream: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
} catch (Exception e) {
System.out.println("Failed closing stream: " + e.getMessage());
System.exit(-1);
}
}
}