Socket Programming Problem.

L

Leo

Hi!
I am doing an assignment that requires something like a "Proxy" that
sits between client and server. However, before I can start
programming functions of the "Proxy", I encounter the problem that the
middleman ("Proxy") can not receive response from the web server. Here
is the simple test program that just do the job of receiving request
from client, sending the request to the web server, reading the
response from the web server and finally sending the response to the
client.

import java.net.*;
import java.io.*;

public final class RequestDiffTest
{
final static String CRLF = "\r\n";

public static void main(String argv[]) throws Exception
{
int port;

// Set the port number.
if (argv.length == 0) {
port = 6789; // If no port number is specified, use the default
port 6789.
System.out.println("Server Port Number: " + port);
} else {
port = Integer.parseInt(argv[0]); // Otherwise, use the port
number specified by the user
System.out.println("Server Port Number: " + port);
}

// Establish the listen socket.
ServerSocket listenSocket = new ServerSocket(port);

// Process HTTP service requests in an infinite loop.
while (true) {
// Listen for a TCP connection request.
Socket connectionSocket = listenSocket.accept();

// Establish a TCP connection to the server.
Socket serverConnectionSocket = new Socket("localhost", 8000);

// Read the request message from client.
BufferedReader inputStreamFromClient = new BufferedReader(new
InputStreamReader(connectionSocket.getInputStream()));
String requestMessage = "";
String messageLine = "";
while ((messageLine = inputStreamFromClient.readLine()).length() !=
0) {
requestMessage += messageLine + CRLF;
}
requestMessage += CRLF;
System.out.println("1. Read Client Request Message:\n" +
requestMessage);

// Send the request message to server.
DataOutputStream outputStreamToServer = new
DataOutputStream(serverConnectionSocket.getOutputStream());
outputStreamToServer.writeBytes(requestMessage);
System.out.println("2. Request Message Sent.");

// SOMETHING WRONG HERE: CAN NOT READ RESPONSE.
// Read the response from the server and send
it to the client.
InputStream inputStreamFromServer =
serverConnectionSocket.getInputStream();
OutputStream outputStreamToClient =
connectionSocket.getOutputStream();

byte[] buff = new byte[1024];
int n = 0;

System.out.println("3. Reading Response From Server.");
while ((n = inputStreamFromServer.read(buff)) != -1) {
System.out.write(buff, 0, n);
outputStreamToClient.write(buff, 0, n);
}

System.out.println("\n4. Successfully Handle The Request.");

inputStreamFromClient.close();
outputStreamToServer.close();
inputStreamFromServer.close();
outputStreamToServer.close();
serverConnectionSocket.close();
connectionSocket.close();
}
}
}

When the program tries to receive response from the web server, the
JVM always say that "Software causes connection to abort: recv fail".
I am sure the web server has already sent the response and I don't
know why the program can't receive response from the server. Could
anyone kindly help me to solve this problem. Thanks in advance!
 
G

Gordon Beaton

When the program tries to receive response from the web server, the
JVM always say that "Software causes connection to abort: recv fail".
I am sure the web server has already sent the response and I don't
know why the program can't receive response from the server.

Don't guess: do you know for a fact that the server has responded, or
that it has even received the request? That's the first thing to
check. Use tcpdump, ethereal or similar tool to inspect the *actual*
traffic between the proxy and the server. You'll need to move the
server to a separate machine from the proxy for that.

That said, you may need to flush() the output stream so the server
actually receives the entire request.

Also there is a lot of confusion regarding stream types in your code,
and I wonder if the data between the client and the server really
passes unmodified through your proxy. It's not a good idea to mix
stream types: if you read with a Reader, then you should write with a
Writer. If you read with an InputStream, then write with an
OutputStream, etc. In particular, are you sure that the correct CR/LF
convention (necessary for HTTP) is preserved through the proxy? Maybe
the server is still waiting for the end of the request.

Normally you should accept connections in a thread that does nothing
but accept connections. For each new connection, create a separate
thread to handle the traffic for that connection, then immediately go
back to accepting connections. In fact I think too that you'll find it
easier to use *two* threads per connection to handle the traffic: one
to handle the traffic from client to server, and one to handle the
traffic in the other direction.

/gordon
 
L

Leo

Gordon Beaton said:
Don't guess: do you know for a fact that the server has responded, or
that it has even received the request? That's the first thing to
check. Use tcpdump, ethereal or similar tool to inspect the *actual*
traffic between the proxy and the server. You'll need to move the
server to a separate machine from the proxy for that.

That said, you may need to flush() the output stream so the server
actually receives the entire request.

Also there is a lot of confusion regarding stream types in your code,
and I wonder if the data between the client and the server really
passes unmodified through your proxy. It's not a good idea to mix
stream types: if you read with a Reader, then you should write with a
Writer. If you read with an InputStream, then write with an
OutputStream, etc. In particular, are you sure that the correct CR/LF
convention (necessary for HTTP) is preserved through the proxy? Maybe
the server is still waiting for the end of the request.

Normally you should accept connections in a thread that does nothing
but accept connections. For each new connection, create a separate
thread to handle the traffic for that connection, then immediately go
back to accepting connections. In fact I think too that you'll find it
easier to use *two* threads per connection to handle the traffic: one
to handle the traffic from client to server, and one to handle the
traffic in the other direction.

/gordon

Gorden, thanks for your reply. I already tested the web server and the
web server already sent the response to the proxy. Sometimes the proxy
can read the response, but sometimes the JVM reported
"java.lang.SocketException: Software causes connection abort: recv
failed" and the JVM indicates the error is at the line 57 "while ((n =
inputStreamFromServer.read(buff)) != -1)". Since the error does not
have any specific pattern and makes it difficult to debug. Any idea
will be deeply appreciated. Thank you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top