2014-03-03 46 views
0

我想开发一个需要modbus/TCP的应用程序。用于Modbus/TCP默认端口是502,当我尝试打开端口502我尝试不同的端口的连接,他们的工作,我得到一个错误。我认为有些东西阻塞了502端口,但我无法弄清楚。如何使用端口502

这是我收到的例外:01-01 00:01:44.309: I/System.out(953): S: Error java.net.BindException: bind failed: EACCES (Permission denied)

我有 “INTERNET” 权限

代码:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class TCPServer extends Thread { 

    public static final int SERVERPORT = 502; 
    public boolean running = true; 
    public boolean receiving = false; 
    private PrintWriter mOut; 

    public TCPServer() { 
    } 

    public void sendMessage(String message) { 
     if (mOut != null && !mOut.checkError()) { 
      mOut.println(message); 
      mOut.flush(); 
     } 
    } 

    @Override 
    public void run() { 
     super.run(); 
     try { 
      while (true) { 
       while (running) { 
        ServerSocket serverSocket = new ServerSocket(SERVERPORT); 
        serverSocket.setSoTimeout(500); 
        Socket tempSckt = new Socket(); 
        boolean isConnected = false; 
        while (!isConnected && running) { 
         try { 
          tempSckt = serverSocket.accept(); 
          isConnected = true; 
         } catch (Exception e) { 

         } 
        } 
        if (running) { 
         System.out.println("connected"); 
         final Socket client = tempSckt; 
         new Thread(new Runnable() { 

          @Override 
          public void run() { 
           receiving = true; 
           try { 
            mOut = new PrintWriter(client 
              .getOutputStream()); 
            BufferedReader in = new BufferedReader(
              new InputStreamReader(client 
                .getInputStream())); 
            while (receiving) { 
             String message = in.readLine(); 
             if (message != null) { 
              // System.out.println(message); 
              byte[] bytes = message.getBytes(); 
              StringBuilder binary = new StringBuilder(); 
              for (byte b : bytes) { 
               int val = b; 
               for (int i = 0; i < 8; i++) { 
                binary.append((val & 128) == 0 ? 0 
                  : 1); 
                val <<= 1; 
               } 
               binary.append(' '); 
              } 
              System.out.println("'" + message 
                + "' to binary: " + binary); 
             } else { 
              receiving = false; 
             } 
            } 

           } catch (Exception e) { 
            System.out.println("S: Error" 
              + e.toString()); 
           } finally { 
            try { 
             client.close(); 
            } catch (Exception e2) { 
            } 
           } 
          } 
         }).start(); 
         isConnected = false; 
        } 

        serverSocket.close(); 
       } 
       Thread.sleep(500); 
      } 
     } catch (Exception e) { 
      System.out.println("S: Error " + e.toString()); 
     } 

    } 
} 

UPDATE

我的应用程序运行作为系统应用程序。我做了必要的配置。我用ps shell命令检查了它。它现在是一个系统应用程序。但是我仍然无法绑定到端口502.

回答

1

1024以下的端口受到限制 - 只有具有root权限的应用才能监听这些端口。当然,你的应用程序没有特权。

这是Linux/Unix上的一般规则(而Android是基于Linux的)。

请参阅this answer了解此限制背后的基本原理。

+0

你的答案后,我尝试和成功地跑到我的应用程序的系统应用。但是我仍然无法绑定到端口502. – MilesDyson

+1

嗯,另一种可能性(如果您正在运行KitKat)是SELinux策略不允许在低端口上侦听。参见[这篇文章](http://www.xda-developers.com/android/easily-change-your-android-selinux-mode/)如何更改SELinux的设置。 – kamituel

+0

我使用一个BeagleBone黑德州仪器的果冻豆4.2 Android的图像。这不是KitKat,但我查找了内核文件并找到了一些SELinux文件。我不完全确定这些与KitKat的SELinux文件是一样的。我尝试了你提供的链接中提到的应用程序。但它自然不起作用,因为它需要KitKat。 – MilesDyson