简体   繁体   English

如何创建仅在本地主机上提供服务的Java Socket对象?

[英]How to create Java Socket object serving on localhost only?

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. 我在这里再次问这个问题( 如何创建仅本地主机的Java套接字? ),因为前面提到的所有方法(仅说通过3个参数创建一个ServerSocket方法)都无法解决我的问题。

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. 我在一个大型Intranet中工作,每次打开一个浏览器时,我都需要输入代理帐户和密码才能访问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. 我想,它应该与某些代理/防火墙有关。

在此处输入图片说明

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 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 我尝试使用telnet,但根本无法连接

在此处输入图片说明

The first problem is that the test code runs both the client and the server. 第一个问题是,测试代码运行客户端和服务器。 In Mytest.main() , the main thread does the following: Mytest.main() ,主线程执行以下操作:

  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) 尝试发送一些消息(但尚未启动ServerSocket
  3. The server is created 服务器已创建
  4. The server waits forever, blocking the main thread on accept() 服务器永远等待,阻塞了accept()上的主线程

As a starter to get your code working. 首先让您的代码正常工作。 Create two test classes TestServer and TestClient , both of these must have main() methods. 创建两个测试类TestServerTestClient ,它们都必须具有main()方法。 Launch TestServer first in it's own Java process. 首先在其自己的Java进程中启动TestServer Next launch TestClient in separate Java process. 接下来,在单独的Java进程中启动TestClient 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() . 创建新线程来管理从accept()返回的新套接字。

Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM