簡體   English   中英

如何創建僅在本地主機上提供服務的Java Socket對象?

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

我在這里再次問這個問題( 如何創建僅本地主機的Java套接字? ),因為前面提到的所有方法(僅說通過3個參數創建一個ServerSocket方法)都無法解決我的問題。

我在一個大型Intranet中工作,每次打開一個瀏覽器時,我都需要輸入代理帳戶和密碼才能訪問Internet。 這就是為什么我希望在本地主機上測試我的套接字程序。

有時,我的客戶端可以連接服務器端,但是通常我必須等待很長時間才能讓她出來。 我想,它應該與某些代理/防火牆有關。

在此處輸入圖片說明

盡管我仔細閱讀了以下所有資源,並相信所有這些資源都值得一讀,但是我仍然無法解決問題。

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

如何確定傳入連接來自本地計算機

我的服務器端代碼

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.");
        }
    }

}

我的客戶端代碼

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.");
    }
}

我的測試代碼

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();
    }

}

我嘗試使用telnet,但根本無法連接

在此處輸入圖片說明

第一個問題是,測試代碼運行客戶端和服務器。 Mytest.main() ,主線程執行以下操作:

  1. 創建一個客戶端(我以為該步驟將失敗)
  2. 嘗試發送一些消息(但尚未啟動ServerSocket
  3. 服務器已創建
  4. 服務器永遠等待,阻塞了accept()上的主線程

首先讓您的代碼正常工作。 創建兩個測試類TestServerTestClient ,它們都必須具有main()方法。 首先在其自己的Java進程中啟動TestServer 接下來,在單獨的Java進程中啟動TestClient 應該工作!

在一切正常之后,您應該在服務器中引入一些並發性。 當前編寫的方式一次只能服務一個客戶。 創建新線程來管理從accept()返回的新套接字。

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM