Question

I ask this question again here ( How to create Java socket that is localhost only? ) 'cause all before mentioned methods (simply to say to create one ServerSocket by 3 parameters method) can not solve my problem.

I am working in one big intranet in which, every time when I open one browser, I need enter my proxy account and password to access internet. This is why I hope to test my socket program on localhost.

Occasionally my Client side can connect the Server side, but usually I have to wait for a long time before she coming out. I suppose, it should be related with some of proxy/firewall.

enter image description here

Although I look over all following resources and believe all of them are well worth reading, but I still can not get my issues out.

http://zerioh.tripod.com/ressources/sockets.html

How to determine an incoming connection is from local machine

My Server Side Code

import java.net.Socket;
import java.net.ServerSocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.InetAddress;

public class Myserver {
    private int serverPort = 8000;
    private ServerSocket serverSock = null;

    public Myserver(int serverPort) {
        this.serverPort = serverPort;

        try {
            /*SocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName("localhost"), serverPort);
            ServerSocket serverSocket = new ServerSocket();
            serverSocket.bind(socketAddress);
            serverSocket.accept();*/
            serverSock = new ServerSocket(serverPort, 0, InetAddress.getByName(null));

        }
        catch (IOException e){
            e.printStackTrace(System.err);
        }
    }
     public void handleConnection(InputStream sockInput, OutputStream sockOutput) {
        while(true) {
            byte[] buf=new byte[1024];
            int bytes_read = 0;
            try {
                // This call to read() will wait forever, until the
                // program on the other side either sends some data,
                // or closes the socket.
                bytes_read = sockInput.read(buf, 0, buf.length);

                // If the socket is closed, sockInput.read() will return -1.
                if(bytes_read < 0) {
                    System.err.println("Tried to read from socket, read() returned < 0,  Closing socket.");
                    return;
                }
                System.err.println("Received "+bytes_read
                                   +" bytes, sending them back to client, data="
                                   +(new String(buf, 0, bytes_read)));
                sockOutput.write(buf, 0, bytes_read);
                // This call to flush() is optional - we're saying go
                // ahead and send the data now instead of buffering
                // it.
                sockOutput.flush();
               // sockOutput.close();

            }
            catch (Exception e){
                System.err.println("Exception reading from/writing to socket, e="+e);
                e.printStackTrace(System.err);
                return;
            }

        }

    }

    public void waitForConnections() {
        Socket sock = null;
        InputStream sockInput = null;
        OutputStream sockOutput = null;
        while (true) {
            try {
                // This method call, accept(), blocks and waits
                // (forever if necessary) until some other program
                // opens a socket connection to our server.  When some
                // other program opens a connection to our server,
                // accept() creates a new socket to represent that
                // connection and returns.
                sock = serverSock.accept();
                System.err.println("Have accepted new socket.");

                // From this point on, no new socket connections can
                // be made to our server until we call accept() again.

                sockInput = sock.getInputStream();
                sockOutput = sock.getOutputStream();
            }
            catch (IOException e){
                e.printStackTrace(System.err);
            }

            // Do something with the socket - read bytes from the
            // socket and write them back to the socket until the
            // other side closes the connection.
            handleConnection(sockInput, sockOutput);

            // Now we close the socket.
            try {
                System.err.println("Closing socket.");
                sock.close();
            }
            catch (Exception e){
                System.err.println("Exception while closing socket.");
                e.printStackTrace(System.err);
            }

            System.err.println("Finished with socket, waiting for next connection.");
        }
    }

}

My Client Side Code

import java.net.Socket;
import java.net.ServerSocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class MyClient {
    private String serverHostname = null;
    private int serverPort =0;
    private byte[] data = null;
    private Socket sock = null;
    private InputStream sockInput = null;
    private OutputStream sockOutput = null;

    public MyClient(String serverHostname, int serverPort, byte[] data){
        this.serverHostname =  serverHostname;
        this.serverPort = serverPort;
        this.data = data;
    }

    public void sendSomeMessages(int iterations) {
        System.err.println("Opening connection to "+serverHostname+" port "+serverPort);
        try {
            sock = new Socket(serverHostname, serverPort);
            sockInput = sock.getInputStream();
            sockOutput = sock.getOutputStream();
        }
        catch (IOException e){
            e.printStackTrace(System.err);
            return;
        }

        System.err.println("About to start reading/writing to/from socket.");

        byte[] buf = new byte[data.length];
        int bytes_read = 0;
        for(int loopi = 1; loopi <= iterations; loopi++) {
            try {
                sockOutput.write(data, 0, data.length); 
                bytes_read = sockInput.read(buf, 0, buf.length);
            }
            catch (IOException e){
                e.printStackTrace(System.err);
            }
            if(bytes_read < data.length) {
                System.err.println("run: Sent "+data.length+" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
            }
            else {
                System.err.println("Sent "+bytes_read+" bytes to server and received them back again, msg = "+(new String(data)));
            }

            // Sleep for a bit so the action doesn't happen to fast - this is purely for reasons of demonstration, and not required technically.
            try { Thread.sleep(50);} catch (Exception e) {}; 
        }
        System.err.println("Done reading/writing to/from socket, closing socket.");

        try {
            sock.close();
        }
        catch (IOException e){
            System.err.println("Exception closing socket.");
            e.printStackTrace(System.err);
        }
        System.err.println("Exiting.");
    }
}

My Test Code

import java.net.*;

public class Mytest {


    public static void main(String[] args) {
    String hostname = "localhost";
        int port = 8000;

        try {
            InetAddress add = InetAddress.getLocalHost();

             System.out.println( add);
        }
        catch (UnknownHostException e)
                {
                     e.printStackTrace(); 
                }


        byte[] data = "my program".getBytes();

        MyClient client = new MyClient(hostname, port, data);
        client.sendSomeMessages(10);   

       Myserver server = new Myserver(port);
        server.waitForConnections();
    }

}

I try telnet, but I can't connect it at all

enter image description here

Was it helpful?

Solution

The first problem is that the test code runs both the client and the server. In Mytest.main(), the main thread does the following:

  1. Creates a client (I would have thought that this step would fail)
  2. Tries to send some messsages (but no ServerSocket has been started)
  3. The server is created
  4. The server waits forever, blocking the main thread on accept()

As a starter to get your code working. Create two test classes TestServer and TestClient, both of these must have main() methods. Launch TestServer first in it's own Java process. Next launch TestClient in separate Java process. This should work!

After you've got everything working, you should introduce some concurrency into your server. The way that it's currently written it can only serve a single client at a time. Create new threads to manage new sockets returned from accept().

Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top