我一直在编写两个Android应用程序,一个是服务器,另一个是客户端。应用程序无法通过我的设备套接字相互连接,每次客户端尝试连接到服务器时,以及服务器尝试创建自己的套接字时,我都会在LogCat中拒绝访问。
在对Matter进行研究之后,我得出结论,在我的android清单文件中包含INTERNET权限将允许两个Apps相互连接。但是,在添加此权限时,我的应用程序现在都会加载崩溃他们之前都运行良好(除了没有彼此连接)所以我不确定发生了什么。我会发布两个应用程序的代码和清单文件,如果您认为需要,我也可以发布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
答案 0 :(得分:0)
这是android 4.0中引入的严格模式的问题。在后台线程上完成的网络工作不在主线程上。在主线程上工作定义活动中的严格模式权限。