0

我一直在编写两个 Android 应用程序,一个是服务器,另一个是客户端。应用程序无法通过我的设备套接字相互连接,每次客户端尝试连接到服务器以及服务器尝试创建自己的套接字时,我都会在 LogCat 中拒绝访问。

在对此事进行研究后,我得出的结论是,在我的 android 清单文件中包含 INTERNET 权限将允许两个应用程序相互连接。但是,在添加此权限后,我的两个应用程序现在都在加载时崩溃。他们之前都运行良好(除了没有相互连接)所以我不确定发生了什么。我将发布这两个应用程序的代码和清单文件,如果您认为需要,我也可以发布 LogCat。

提前喝彩。

服务器代码:

package com.example.simplerclienttest;

import java.io.IOException;  
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {


    Double lat=50.0, lng= 50.0, speed=(Math.random()*20), heading= 0.010011011, latB4, lngB4; 
    int time = 1;
    int trackId; 


    public void go(){

        try{
            ServerSocket serverSock = new ServerSocket(20000);

            while(true){

                Socket sock = serverSock.accept();

                PrintWriter writer = new PrintWriter(sock.getOutputStream());
                String header = getHeader();
                writer.write(header);
                writer.flush();
                writer.close();

            }

        }catch (IOException ex){
            ex.printStackTrace();
        }

    }

    public String getHeader(){
        latB4= lat;
        lngB4= lng;
        lat = lat + ((Math.random()-0.5)/100);
        lng = lng + ((Math.random()-0.5)/100);
        String Heading = "CBS";
        time = time + 1;
        trackId = 1;
        int depth = 0;
        speed = speed + ((Math.random()-0.5)*2);
        if((lat - latB4)>0 && (lng-lngB4)>0){
            heading = (((Math.atan(Math.abs(lng)/Math.abs(lat)))*180)/Math.PI);
        }else{
            if((lat - latB4)<0 && (lng-lngB4)>0){
                heading= (90 + (((Math.atan(Math.abs(lat)/Math.abs(lng)))*180)/Math.PI));
            }else{
                if((lat - latB4)<0 && (lng-lngB4)<0){
                    heading= (180 + (((Math.atan(Math.abs(lng)/Math.abs(lat)))*180)/Math.PI));  
                }else{
                    if((lat - latB4)>0 && (lng-lngB4)<0){
                        heading= (270 + (((Math.atan(Math.abs(lat)/Math.abs(lng)))*180)/Math.PI));
                    }else{
                        if((lat - latB4)==0 && (lng-lngB4)<0){
                            heading= 270.0;
                        }else{
                            if((lat - latB4)==0 && (lng-lngB4)>0){
                                heading = 90.0;
                            }else{
                                if((lat - latB4)>0 && (lng-lngB4)==0){
                                    heading= 0.0;
                                }else{
                                    if((lat - latB4)<0 && (lng-lngB4)==0){
                                        heading = 180.0;
                        }else{}}}}}}}}


        return(Heading+","+time+","+trackId+","+lat+","+lng+","+depth+","+speed+","+heading);
    }

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        go();


    }

    }

服务器清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.simplerclienttest"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.simplerclienttest.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

客户端代码:

package com.example.clienttest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.widget.TextView;

public class ClientTestMain extends Activity {

final Handler myHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_client_test_main);


    Timer myTimer = new Timer();
    myTimer.schedule(new TimerTask(){
        @Override
        public void run(){
            UpdateGUI();}},0,1000);
        }


final Runnable myRunnable = new Runnable(){
            @Override
            public void run(){

                TextView Header = (TextView) findViewById(R.id.textView1);
                TextView Time = (TextView) findViewById(R.id.textView7);
                TextView TrackId = (TextView) findViewById(R.id.textView2);
                TextView Latitude = (TextView) findViewById(R.id.textView3);
                TextView Longitude = (TextView) findViewById(R.id.textView4);
                TextView Depth = (TextView) findViewById(R.id.textView5);
                TextView Speed = (TextView) findViewById(R.id.textView6);
                TextView Bearing = (TextView) findViewById(R.id.textView8);

                try{
                    while(true){
                    Socket infoSocket = new Socket("127.0.0.1", 20000);
                    InputStreamReader stream = new InputStreamReader(infoSocket.getInputStream());
                    BufferedReader reader = new BufferedReader(stream);
                    String message = reader.readLine();
                    String[] op = message.split(",");
                    Header.setText(op[0]);
                    Time.setText(op[1]);
                    TrackId.setText(op[2]);
                    Latitude.setText(op[3]);
                    Longitude.setText(op[4]);
                    Depth.setText(op[5]);
                    Speed.setText(op[6]);
                    Bearing.setText(op[7]);
                    TimeUnit.SECONDS.sleep(1);
                    }
                }catch(IOException ex){
                    ex.printStackTrace();
                }catch (InterruptedException e) {
                }

            }};



  private void UpdateGUI(){
      myHandler.post(myRunnable);
  }



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.client_test_main, menu);
    return true;
}

}

客户清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.clienttest"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.clienttest.ClientTestMain"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

如果看到 LogCat 会有所帮助,请您留言并添加它:) 谢谢。

这是具有 INTERNET 权限的客户端崩溃的 LogCat:

09-05 14:12:59.500: D/AndroidRuntime(16366): Shutting down VM
09-05 14:12:59.500: W/dalvikvm(16366): threadid=1: thread exiting with uncaught exception (group=0x40bea1f8)
09-05 14:12:59.500: E/AndroidRuntime(16366): FATAL EXCEPTION: main
09-05 14:12:59.500: E/AndroidRuntime(16366): android.os.NetworkOnMainThreadException
09-05 14:12:59.500: E/AndroidRuntime(16366):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at libcore.io.IoBridge.connect(IoBridge.java:112)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.Socket.startupSocket(Socket.java:566)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.Socket.tryAllAddresses(Socket.java:127)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.Socket.<init>(Socket.java:177)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.net.Socket.<init>(Socket.java:149)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at com.example.clienttest.ClientTestMain$1.run(ClientTestMain.java:50)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at android.os.Handler.handleCallback(Handler.java:605)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at android.os.Handler.dispatchMessage(Handler.java:92)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at android.os.Looper.loop(Looper.java:137)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at android.app.ActivityThread.main(ActivityThread.java:4514)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.lang.reflect.Method.invokeNative(Native Method)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at java.lang.reflect.Method.invoke(Method.java:511)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
09-05 14:12:59.500: E/AndroidRuntime(16366):    at dalvik.system.NativeStart.main(Native Method)

这是没有 INTERNET 权限的客户端的 LogCat:

09-05 14:15:29.062: W/System.err(16707): java.net.SocketException: socket failed: EACCES (Permission denied)
09-05 14:15:29.062: W/System.err(16707):    at libcore.io.IoBridge.socket(IoBridge.java:573)
09-05 14:15:29.062: W/System.err(16707):    at java.net.PlainSocketImpl.create(PlainSocketImpl.java:201)
09-05 14:15:29.062: W/System.err(16707):    at java.net.Socket.startupSocket(Socket.java:559)
09-05 14:15:29.062: W/System.err(16707):    at java.net.Socket.tryAllAddresses(Socket.java:127)
09-05 14:15:29.062: W/System.err(16707):    at java.net.Socket.<init>(Socket.java:177)
09-05 14:15:29.062: W/System.err(16707):    at java.net.Socket.<init>(Socket.java:149)
09-05 14:15:29.062: W/System.err(16707):    at com.example.clienttest.ClientTestMain$1.run(ClientTestMain.java:50)
09-05 14:15:29.062: W/System.err(16707):    at android.os.Handler.handleCallback(Handler.java:605)
09-05 14:15:29.062: W/System.err(16707):    at android.os.Handler.dispatchMessage(Handler.java:92)
09-05 14:15:29.062: W/System.err(16707):    at android.os.Looper.loop(Looper.java:137)
09-05 14:15:29.062: W/System.err(16707):    at android.app.ActivityThread.main(ActivityThread.java:4514)
09-05 14:15:29.062: W/System.err(16707):    at java.lang.reflect.Method.invokeNative(Native Method)
09-05 14:15:29.062: W/System.err(16707):    at java.lang.reflect.Method.invoke(Method.java:511)
09-05 14:15:29.070: W/System.err(16707):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
09-05 14:15:29.070: W/System.err(16707):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
09-05 14:15:29.070: W/System.err(16707):    at dalvik.system.NativeStart.main(Native Method)
09-05 14:15:29.070: W/System.err(16707): Caused by: libcore.io.ErrnoException: socket failed: EACCES (Permission denied)
09-05 14:15:29.070: W/System.err(16707):    at libcore.io.Posix.socket(Native Method)
09-05 14:15:29.070: W/System.err(16707):    at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:181)
09-05 14:15:29.070: W/System.err(16707):    at libcore.io.IoBridge.socket(IoBridge.java:558)
09-05 14:15:29.070: W/System.err(16707):    ... 15 more
4

1 回答 1

0

这是在android 4.0中引入的严格模式的问题。根据这个网络工作在后台线程而不是在主线程上完成。要在主线程上工作,请在活动中定义严格模式权限。

于 2013-12-01T18:57:40.427 回答