【问题标题】:How do change the reply port for a serversocket connection in JAVA如何在 JAVA 中更改 serversocket 连接的回复端口
【发布时间】:2012-06-23 20:00:00
【问题描述】:


我正在尝试为充当 TCP/IP 服务器的硬连线设备编写一个模拟器。
我有一个连接到该服务器并进行通信的 VB6 程序,但是这会间歇性地失败,我需要确定出了什么问题,所以我正在编写一个程序来模拟服务器。
我已经构建了以下 Java 程序来侦听来自 VB 程序的连接并使用与服务器设备相同的信息进行响应。

public class ServerSim {

public static void main(String[] args){
    int port = 23;
    System.out.println("[Listening for Connection]");
    try{
        ServerSocket ss;
        ss = new ServerSocket(port);
        Socket s;

        // The program will wait here until a connection is made.
        s = ss.accept();

        // Print what client we're connected to.
        String client;
        client = s.getInetAddress().toString();
        String localPort = Integer.toString(s.getLocalPort());
        String portNo = Integer.toString(s.getPort());

        System.out.println("[Connected to "+client +"] Port:" + portNo + " localPort: " + localPort);

        //Set up Scanner / Writer to read / write data to client.
        Scanner in;
        //Scanner sc = new Scanner(System.in);

        in = new Scanner(s.getInputStream());
        PrintWriter out;
        out = new PrintWriter(s.getOutputStream(),true);

        PrintWriter log = openWriter("Log.txt");

        // Establish a 5second connection
        s.setSoTimeout(5000);

        try{
            boolean result = establishConnection(in, out);
            String input = in.nextLine();
            System.out.println("Recieved: " + input);
            String response = input;
            out.println(response);
            System.out.println("Responded: " + response);
            log.println(input + "->" + response);
       }
       catch(Exception e){
           System.err.println("EXC: "+e.getMessage());                   
           e.printStackTrace();                   
       }
       System.out.println("[Closing Connections]");
       in.close();
        out.close();
        log.close();
        s.close();
        ss.close();

    }catch(Exception e){
        e.printStackTrace();            
    }        
}
    private static boolean establishConnection(Scanner in, PrintWriter out){
        // we have a connnection - Start by outputtinga  welcome message.       
        out.print("Welcome Session 0\r\n");
        out.flush();            
        out.print("User:\r\n");
        out.flush();
        System.out.println("[Welcome sent - Waiting Response]");
        String input = in.nextLine(); // Recieve the first line.  Should be a User
        System.out.println("[Recieved '"+input+"' - Sending anticipated reply]");
        out.println("Password:");
        input = in.nextLine(); // Recieve the first line.  Should be a User
        System.out.println("[Recieved '"+input+"' - Sending anticipated reply]");
        out.println("User Logged in");      
        return true;
    }
   private static PrintWriter openWriter(String name){
        try{
            File file = new File(name);
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                    new FileWriter(file, true)),true);
            return out;
        }
        catch(IOException e){
            System.out.println("I/O Error");
            System.exit(0);
        }
        return null;
    }

}

问题是VB1程序不接受我程序的输入。

我将成功设备的网络数据包捕获与我自己程序的流量捕获进行了比较,所有相关的内容都是相同的...除了回复端口。
在我的程序中,serversocket 随机分配一个端口来响应 VB6 程序,但是当 VB6 程序连接到我试图模拟的物理设备时,设备只回复端口 1602。

我的问题是,当我正在监听端口 23 进行连接时(这很好),我如何获得创建的套接字以在端口 1602 上进行回复,而不是在 2000 - 3000 标记附近随机跳转?

我能看到的所有回复和问题都围绕着套接字或多线程,而没有锁定等待连接的端口。
如果这不是一个观众,那么有人可以指出我想要实现的 UI 的更好解决方案吗?
我知道有人会说为什么不用实际设备设置一个装备,但它们很贵而且我没有现成的备用设备来安装钻机。那个,现在这个问题已经向我提出,我不禁要找出发生了什么! :-)

1编辑:我无法询问 VB 程序,因为它使用一系列 ActiveX 与设备通信并处理协议。这就是我试图找到的问题的根源,所以我不想写出来。

【问题讨论】:

    标签: java tcp port serversocket


    【解决方案1】:

    如果您想在端口 1602 上回复 vb-app(并且 vb-app 还没有使用其一侧的端口 1602),您将需要另一个(新)套接字。

    ServerSocket.accept();
    

    返回java.net.Socket。此连接由 4 个属性标识:client-port、client-ip、server-port、server-ip。

    不是服务器(您的程序)随机分配(您所称的)回复端口,而是客户端(vb-app)。如果客户端不这样做,服务器将不知道它应该将响应数据包发送到哪里。

    您可能想要创建一个java.net.Socket,其中包含 vb 应用程序的 ip 和端口 1602。vb-app 很可能充当客户端服务器。

    【讨论】:

      【解决方案2】:

      试试 java.net.Socket .. 我给你我的代码的 sn-p,我用它来模拟在指定端口上运行的服务器。希望对你有用....

      import java.io.BufferedReader;
      
      import java.io.IOException;
      
      import java.io.InputStreamReader;
      
      import java.io.PrintWriter;
      
      import java.net.ServerSocket;
      
      import java.net.Socket;
      
      public class ServerTest {
      
          ServerSocket s;
      
          public void go() {
      
              try {
                  s = new ServerSocket(44457);
      
                  while (true) {
      
                      Socket incoming = s.accept();
                      Thread t = new Thread(new MyCon(incoming));
                      t.start();
                  }
              } catch (IOException e) {
      
                  e.printStackTrace();
              }
      
          }
      
          class MyCon implements Runnable {
      
              Socket incoming;
      
              public MyCon(Socket incoming) {
      
                  this.incoming = incoming;
              }
      
              @Override
              public void run() {
      
                  try {
                      PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
                              true);
                      InputStreamReader isr = new InputStreamReader(
                              incoming.getInputStream());
                      BufferedReader br = new BufferedReader(isr);
                      String inp = null;
      
                      boolean isDone = true;
      
                      System.out.println("TYPE : BYE");
                      System.out.println();
                      while (isDone && ((inp = br.readLine()) != null)) {
      
                          System.out.println(inp);
                          if (inp.trim().equals("BYE")) {
                              System.out
                                      .println("THANKS FOR CONNECTING...Bye for now");
                              isDone = false;
                              s.close();
                          }
      
                      }
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      try {
                          s.close();
                      } catch (IOException e1) {
                          // TODO Auto-generated catch block
                          e1.printStackTrace();
                      }
                      e.printStackTrace();
                  }
      
              }
      
          }
      
          public static void main(String[] args) {
      
              new ServerTest().go();
      
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        “serversocket为响应随机分配一个端口”。

        我不明白那句话。 ServerSocket 接受的Socket 的本地端口号为23(与ServerSocket 正在侦听的端口相同),以及由客户端在连接时确定的远程端口号。这不受服务器程序的控制。设备可能只使用端口 1602 作为其输出端口,但 VB 程序几乎可以肯定让操作系统决定端口号。

        我认为您需要根据这些信息重新分析您的观察结果。

        【讨论】:

          猜你喜欢
          • 2011-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-13
          • 1970-01-01
          相关资源
          最近更新 更多