Reputation: 6365
Is it possible for a server to know that the client has finished sending it data and is now ready for a response - regardless (and without knowledge) of the application protocol?
Edit: Think about creating a proxy sever. You can't affect protocols, you don't know the applicative details of each protocol (so you don't know when a stream "ends"). Regarding "client may close the input stream" - that's true, but apparently clients do not actually close the stream (has to do with reuse?). This is empirically tested with web browsers.
I may be barking on the wrong tree though - for that proxy server scenario, wouldn't copying the stream to the output stream of the "other end" be enough? However, how would the other end "know" that the stream has ended?
See this program:
public class Test {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8081, 100, InetAddress.getByName("localhost"));
final Socket socket1 = new Socket("www.google.com", 80);
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
public void run() {
try {
final InputStream inputStream = socket1.getInputStream();
final OutputStream outputStream = socket.getOutputStream();
readwrite(inputStream, outputStream, false);
} catch (IOException e) {
e.printStackTrace();
}
}
});
final InputStream inputStream = socket.getInputStream();
final OutputStream outputStream1 = socket1.getOutputStream();
readwrite(inputStream, outputStream1, true);
}
private static void readwrite(InputStream inputStream, OutputStream outputStream1, boolean x) throws IOException {
final byte[] bytes = new byte[4];
int read = -1;
while ((read = inputStream.read(bytes)) != -1) {
System.out.println((x?"s ":"r ") + new String(bytes));
outputStream1.write(bytes, 0, read);
}
}
}
Instead of doing what you'd think it would do (proxy for www.google.com) it just hangs. The thread that's supposed to read from google and write to the local socket doesn't detect anything on that input stream.
Edit2: DOH! put me in the stupid corner. Forgot to "start" the thread. Back to my original question - how do I know the stream has ended?
Edit3: Well, my problem was something completely different (had to do with POST, Transfer-Encoding and HttpClient-annoying-internal-cache-that-can't-be-turned-off). For fairness sake, I'll accept the answer that answers the original question best.
Upvotes: 2
Views: 217
Reputation: 8466
If 'finished' means that inbound or outbound stream of TCP is closed (so called half close connection), then it is possible. Inbound stream is closed if inputStream.read(bytes)
returns -1.
If 'finished' means something else, then the answer is no.
If you are going to implement a general purpose proxy, then you should wait data from both sockets at the same time. And write any incoming data to other socket. And you should also stop reading a socket, if the another socket is not writable. Or else you must buffer data. Proxy should also handle half closed connections.
Don't try to detect, when delivered protocol has message boundary, because some protocols may stream data to both directions all the time.
Upvotes: 1
Reputation: 10250
The client's TCP session will have both an inbound and outbound stream. It is possible for the client to close its outbound stream after sending its request, leaving its inbound stream open to receive the response. The server would detect this condition, while still being able to reply.
Upvotes: 0
Reputation: 2116
No - but you can use non blocking reads with timeout which will tell you that no more data is coming in. That may solve the problem.
Upvotes: 0