Python服务器与Android客户端的Socket编程
我想设置一个套接字接口。在电脑这边,我用Python写了一个非常简单的套接字服务器来测试连接:
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 5000 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
然后,一个安卓客户端应用会连接到电脑:
package com.example.androidsocketclient;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
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.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "192.168.2.184";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
但是,我无法在电脑和安卓设备之间建立连接。有什么办法可以解决这个问题吗?
3 个回答
1
你正在用 socket.gethostname()
运行服务器,而你想把安卓应用连接到 "192.168.2.184"
这个地址。
试着在这个地址上运行 server
。
s = socket.socket()
host = "192.168.2.184"
port = 5000
s.bind((host, port))
4
你需要在代码中输入IP地址和端口号,但如果没有这些信息该怎么办呢?看看下面的例子:
public void connect() {
new Thread(new Runnable(){
@Override
public void run() {
try {
client = new Socket(ipadres, portnumber);
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write("HI "); // write the message to output stream
printwriter.flush();
printwriter.close();
connection = true;
Log.d("socket", "connected " + connection);
// Toast in background becauase Toast cannnot be in main thread you have to create runOnuithread.
// this is run on ui thread where dialogs and all other GUI will run.
if (client.isConnected()) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//Do your UI operations like dialog opening or Toast here
connect.setText("Connected");
Toast.makeText(getApplicationContext(), "Messege send", Toast.LENGTH_SHORT).show();
}
});
}
}
catch (UnknownHostException e2){
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//Do your UI operations like dialog opening or Toast here
Toast.makeText(getApplicationContext(), "Unknown host please make sure IP address", Toast.LENGTH_SHORT).show();
}
});
}
catch (IOException e1) {
Log.d("socket", "IOException");
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//Do your UI operations like dialog opening or Toast here
Toast.makeText(getApplicationContext(), "Error Occured"+ " " +to, Toast.LENGTH_SHORT).show();
}
});
}
}
}).start();
}
只需要通过编辑框让用户输入IP地址和端口号,然后你只需复制粘贴代码就可以了。
祝你好运!如果不成功,可以再在这里发帖询问。
2
因为你没有说明你是使用私有IP还是公共IP,所以可能会有以下几种问题:
如果你使用的是私有连接,那么显然这不是路由器或防火墙的问题,因为你们在同一个网络下,所以可能性就少了:
- 服务器上那个IP的端口没有任何服务在监听
- 服务器上有本地防火墙在阻止这个连接请求
- 你没有使用WIFI,所以你不在同一个网络下。
你应该确保可以通过其他方式打开这个服务,这样可以帮助你找出问题所在。如果你已经这样做过了,我建议你使用一些调试工具来跟踪TCP数据包(我也不知道你在目标机器上使用的是什么操作系统;如果是某种Linux发行版,tcpdump
可能会有帮助;在Windows系统下,WireShark
可能会有用)。
如果你使用的是公共IP,那就要考虑路由器可能在阻止连接,这意味着服务器上的这个端口可能是关闭或被过滤的,你只需要把它打开。
这一切都假设你在你的AndroidManifest.xml文件中有android.permission.INTERNET
的权限。