我的客户端服务器应用在Eclipse模拟器中运行正常,但在真实安卓手机上不运行
我写了一个客户端-服务器程序,客户端是安卓应用,服务器是用Python写的。在客户端,我在一个输入框里输入数据,然后按下一个按钮,数据就通过互联网发送到服务器,服务器再把这些数据保存到我的SQLite数据库里。我的服务器和手机设备通过WIFI连接到一个调制解调器,所以我在程序中使用了本地IP地址,并且用socket来传输数据。
我遇到的问题是这样的:我的应用在模拟器上运行得很好,当服务器和模拟器在同一台电脑上时没有问题。但是当我在真实的安卓设备上运行我的应用时,它无法连接到服务器。虽然我的应用可以运行,但当我按下按钮时,它会停止并退出。
谢谢你的帮助。我确信我的Python服务器是正确的,因为我用telnet测试过,客户端和服务器之间的连接没有问题。我觉得我的客户端程序可能有问题。
这是我的服务器端代码,使用Python:
#! /usr/bin/python3
import socket
import sqlite3
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.4"
port = 4444
print (host)
print (port)
serversocket.bind((host, port))
serversocket.listen(5)
print ('server started and listening')
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
row=data.split(" ", 3)
a=row[0]
b=row[1]
c=row[2]
conn = sqlite3.connect('test.db')
print ("Opened database successfully")
conn.execute("INSERT INTO victims values (?,?,?)",(a,b,c));
conn.commit()
print ("Records created successfully")
conn.close()
s.close ()
这是我的客户端代码,使用安卓:
package com.alizade.m;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class Client3 extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField1;
private EditText textField2;
private EditText textField3;
private Button button;
private String messsage1;
private String messsage2;
private String messsage3;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textField1 = (EditText) findViewById(R.id.editText1); //reference to the text field
textField2 = (EditText) findViewById(R.id.editText2); //reference to the text field
textField3 = (EditText) findViewById(R.id.editText3); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
final TextView tv=(TextView) findViewById(R.id.textView1);
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
messsage1 = textField1.getText().toString(); //get the text message on the text field
textField1.setText(""); //Reset the text field to blank
messsage2 = textField2.getText().toString(); //get the text message on the text field
textField2.setText(""); //Reset the text field to blank
messsage3 = textField3.getText().toString(); //get the text message on the text field
textField3.setText("");
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.4");
client = new Socket(serverAddr, 4444); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage1); //write the message to output stream
printwriter.write(" ");
printwriter.write(messsage2);
printwriter.write(" ");
printwriter.write(messsage3);
printwriter.flush();
printwriter.close();
tv.setText("sent");
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
这是LogCat的内容:
06-09 13:27:15.127: D/AndroidRuntime(453): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
06-09 13:27:15.127: D/AndroidRuntime(453): CheckJNI is ON
06-09 13:27:18.707: D/AndroidRuntime(453): Calling main entry com.android.commands.pm.Pm
06-09 13:27:18.917: D/AndroidRuntime(453): Shutting down VM
06-09 13:27:18.957: I/AndroidRuntime(453): NOTE: attach of thread 'Binder Thread #3' failed
06-09 13:27:19.047: D/dalvikvm(453): GC_CONCURRENT freed 100K, 72% free 296K/1024K, external 0K/0K, paused 19ms+10ms
06-09 13:27:19.077: D/jdwp(453): Got wake-up signal, bailing out of select
06-09 13:27:19.077: D/dalvikvm(453): Debugger has detached; object registry had 1 entries
06-09 13:27:21.846: D/AndroidRuntime(464): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
06-09 13:27:21.856: D/AndroidRuntime(464): CheckJNI is ON
06-09 13:27:22.867: D/SntpClient(70): request time failed: java.net.SocketException: Address family not supported by protocol
06-09 13:27:25.378: D/AndroidRuntime(464): Calling main entry com.android.commands.pm.Pm
06-09 13:27:25.967: D/dalvikvm(230): GC_EXPLICIT freed 2K, 54% free 2545K/5511K, external 1625K/2137K, paused 212ms
06-09 13:27:26.007: W/ActivityManager(70): No content provider found for:
06-09 13:27:26.177: W/ActivityManager(70): No content provider found for:
06-09 13:27:26.257: D/PackageParser(70): Scanning package: /data/app/vmdl-1838012416.tmp
06-09 13:27:26.807: I/PackageManager(70): Removing non-system package:com.alizade.m
06-09 13:27:26.807: I/ActivityManager(70): Force stopping package com.alizade.m uid=10034
06-09 13:27:27.257: I/Process(70): Sending signal. PID: 444 SIG: 9
06-09 13:27:27.577: E/InputDispatcher(70): channel '4068bb68 com.alizade.m/com.alizade.m.Client3 (server)' ~ Consumer closed input channel or an error occurred. events=0x8
06-09 13:27:27.577: E/InputDispatcher(70): channel '4068bb68 com.alizade.m/com.alizade.m.Client3 (server)' ~ Channel is unrecoverably broken and will be disposed!
06-09 13:27:27.957: I/WindowManager(70): WINDOW DIED Window{4068bb68 com.alizade.m/com.alizade.m.Client3 paused=false}
06-09 13:27:28.126: W/WindowManager(70): Failed looking up window
06-09 13:27:28.126: W/WindowManager(70): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@406119b0 does not exist
06-09 13:27:28.126: W/WindowManager(70): at com.android.server.WindowManagerService.windowForClientLocked(WindowManagerService.java:8174)
06-09 13:27:28.126: W/WindowManager(70): at com.android.server.WindowManagerService.windowForClientLocked(WindowManagerService.java:8165)
06-09 13:27:28.126: W/WindowManager(70): at com.android.server.WindowManagerService$WindowState$DeathRecipient.binderDied(WindowManagerService.java:7024)
06-09 13:27:28.126: W/WindowManager(70): at android.os.BinderProxy.sendDeathNotice(Binder.java:381)
06-09 13:27:28.126: W/WindowManager(70): at dalvik.system.NativeStart.run(Native Method)
06-09 13:27:28.146: I/WindowManager(70): WIN DEATH: null
06-09 13:27:28.926: W/InputManagerService(70): Got RemoteException sending setActive(false) notification to pid 444 uid 10034
06-09 13:27:30.138: D/dalvikvm(126): GC_EXTERNAL_ALLOC freed 37K, 44% free 3459K/6151K, external 6952K/7268K, paused 596ms
06-09 13:27:33.717: D/PackageManager(70): Scanning package com.alizade.m
06-09 13:27:33.788: I/PackageManager(70): Package com.alizade.m codePath changed from /data/app/com.alizade.m-1.apk to /data/app/com.alizade.m-2.apk; Retaining data and using new
06-09 13:27:34.008: I/PackageManager(70): Unpacking native libraries for /data/app/com.alizade.m-2.apk
06-09 13:27:34.247: D/installd(35): DexInv: --- BEGIN '/data/app/com.alizade.m-2.apk' ---
06-09 13:27:35.489: D/dalvikvm(473): DexOpt: load 124ms, verify+opt 435ms
06-09 13:27:35.550: D/installd(35): DexInv: --- END '/data/app/com.alizade.m-2.apk' (success) ---
06-09 13:27:35.606: I/ActivityManager(70): Force stopping package com.alizade.m uid=10034
06-09 13:27:35.626: W/PackageManager(70): Code path for pkg : com.alizade.m changing from /data/app/com.alizade.m-1.apk to /data/app/com.alizade.m-2.apk
06-09 13:27:35.626: W/PackageManager(70): Resource path for pkg : com.alizade.m changing from /data/app/com.alizade.m-1.apk to /data/app/com.alizade.m-2.apk
06-09 13:27:35.647: D/PackageManager(70): Activities: com.alizade.m.Client3
06-09 13:27:36.430: D/dalvikvm(230): GC_EXPLICIT freed 7K, 54% free 2543K/5511K, external 1625K/2137K, paused 160ms
06-09 13:27:36.898: I/installd(35): move /data/dalvik-cache/data@app@com.alizade.m-2.apk@classes.dex -> /data/dalvik-cache/data@app@com.alizade.m-2.apk@classes.dex
06-09 13:27:36.906: D/PackageManager(70): New package installed in /data/app/com.alizade.m-2.apk
06-09 13:27:36.936: W/PackageManager(70): Not granting permission android.permission.BROADCAST_WAP_PUSH to package com.alizade.m (protectionLevel=2 flags=0x8be46)
06-09 13:27:37.846: I/ActivityManager(70): Force stopping package com.alizade.m uid=10034
06-09 13:27:38.490: D/dalvikvm(70): GC_EXPLICIT freed 524K, 49% free 4352K/8519K, external 3511K/3903K, paused 541ms
06-09 13:27:38.769: D/dalvikvm(153): GC_EXPLICIT freed 74K, 51% free 2879K/5831K, external 4698K/5604K, paused 907ms
06-09 13:27:39.497: W/RecognitionManagerService(70): no available voice recognition services found
06-09 13:27:41.347: D/dalvikvm(70): GC_EXPLICIT freed 192K, 50% free 4328K/8519K, external 3511K/3903K, paused 954ms
06-09 13:27:41.557: I/installd(35): unlink /data/dalvik-cache/data@app@com.alizade.m-1.apk@classes.dex
06-09 13:27:41.747: D/dalvikvm(181): GC_EXPLICIT freed 95K, 52% free 2759K/5639K, external 1625K/2137K, paused 2891ms
06-09 13:27:41.877: D/AndroidRuntime(464): Shutting down VM
06-09 13:27:42.317: D/dalvikvm(464): GC_CONCURRENT freed 100K, 72% free 294K/1024K, external 0K/0K, paused 138ms+3ms
06-09 13:27:42.417: D/jdwp(464): Got wake-up signal, bailing out of select
06-09 13:27:42.417: D/dalvikvm(464): Debugger has detached; object registry had 1 entries
06-09 13:27:45.466: D/AndroidRuntime(478): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
06-09 13:27:45.466: D/AndroidRuntime(478): CheckJNI is ON
06-09 13:27:49.330: D/AndroidRuntime(478): Calling main entry com.android.commands.am.Am
06-09 13:27:49.580: I/ActivityManager(70): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.alizade.m/.Client3 } from pid 478
06-09 13:27:50.629: D/AndroidRuntime(478): Shutting down VM
06-09 13:27:50.669: I/AndroidRuntime(478): NOTE: attach of thread 'Binder Thread #3' failed
06-09 13:27:50.857: I/ActivityManager(70): Start proc com.alizade.m for activity com.alizade.m/.Client3: pid=487 uid=10034 gids={3003}
06-09 13:27:51.447: D/dalvikvm(478): GC_CONCURRENT freed 101K, 69% free 318K/1024K, external 0K/0K, paused 10ms+7ms
06-09 13:27:51.687: D/jdwp(478): Got wake-up signal, bailing out of select
06-09 13:27:51.687: D/dalvikvm(478): Debugger has detached; object registry had 1 entries
06-09 13:27:56.520: D/dalvikvm(329): GC_EXPLICIT freed 3K, 54% free 2537K/5511K, external 1625K/2137K, paused 11133ms
06-09 13:27:56.817: I/ActivityManager(70): Displayed com.alizade.m/.Client3: +6s260ms
06-09 13:28:05.378: D/dalvikvm(290): GC_EXPLICIT freed 8K, 55% free 2595K/5703K, external 1625K/2137K, paused 233ms
06-09 13:28:10.506: D/dalvikvm(153): GC_EXPLICIT freed 65K, 50% free 2968K/5831K, external 4748K/5604K, paused 333ms
06-09 13:28:12.917: W/KeyCharacterMap(487): No keyboard for id 0
06-09 13:28:12.927: W/KeyCharacterMap(487): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
1 个回答
你的服务器上这个端口的防火墙是不是关了?可能是防火墙把它给挡住了。试着查看一下LogCat的输出,看看有没有异常、未捕获的异常或者空指针错误。
更新:
你在你的安卓manifest .xml文件里有必要的权限吗?
首先,如果你给InetAddress提供了你的IP地址,那就把方法改成:
InetAddress serverAddr = InetAddress.getByName("192.168.1.4");
改成:
InetAddress serverAddr = InetAddress.getByAddress(new byte [] {192, 168, 1, 4});
你还可以在定义按钮点击监听器的地方设置一个断点,然后一步一步地查看你的应用在哪儿崩溃(在Eclipse里按F6),当然要把设备连接到电脑上。
更新:
哎呀,我现在都脸红了 :) 我怎么没注意到你是在主线程上做网络通信呢。你需要在一个线程或者异步任务中进行。
你可以用两种方式来实现,我觉得更好的方式是异步任务:
private Socket client;
private PrintWriter printwriter;
private EditText textField1;
private EditText textField2;
private EditText textField3;
private Button button;
private String messsage1;
private String messsage2;
private String messsage3;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField1 = (EditText) findViewById(R.id.editText1); //reference to the text field
textField2 = (EditText) findViewById(R.id.editText2); //reference to the text field
textField3 = (EditText) findViewById(R.id.editText3); //reference to the text field
button = (Button) findViewById(R.id.button1); //reference to the send button
tv=(TextView) findViewById(R.id.textView1);
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
messsage1 = textField1.getText().toString(); //get the text message on the text field
textField1.setText(""); //Reset the text field to blank
messsage2 = textField2.getText().toString(); //get the text message on the text field
textField2.setText(""); //Reset the text field to blank
messsage3 = textField3.getText().toString(); //get the text message on the text field
textField3.setText("");
new ServerPingPong().execute();
}
});
}
private class ServerPingPong extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... params) {
try {
InetAddress serverAddr = InetAddress.getByName("192.168.0.69");
client = new Socket(serverAddr, 4444); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage1); //write the message to output stream
printwriter.write(" ");
printwriter.write(messsage2);
printwriter.write(" ");
printwriter.write(messsage3);
printwriter.flush();
printwriter.close();
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
tv.setText("sent");
}
}
或者用更简单的方法,但没那么炫酷 :) :
new Thread() {
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("192.168.1.4");
client = new Socket(serverAddr, 4444); //connect to server
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage1); //write the message to output stream
printwriter.write(" ");
printwriter.write(messsage2);
printwriter.write(" ");
printwriter.write(messsage3);
printwriter.flush();
printwriter.close();
tv.setText("sent");
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
这两种方法我都测试过,都是有效的。
其次,你没有提供正确的LogCat日志。几乎没有关于你应用运行的信息。试着了解一下如何使用LogCat,这对找错误很有帮助。你可能遇到了NetworkOnMainThread的致命异常。