http://blog.163.com/fanning_7213/blog/static/2496505201137101721665/
第一位作者写的很好 现在复制如下
开发的过程中遇到一个问题:android的模拟器有个很诡异的特点,就是访问网络的时候只可以从模拟器主动往出去连。但是却无法主的从外面连接模拟器,这个特点和NAT几乎完全一样,具有单向连接的特性。实际开发中我们希望模拟器像一台独立的手机一样,能和处于同一局域网中的手机进行端对端的通信。这时就需要做端口重定向。
假定- A是PC机 - B是你的第一个模拟器- C是你的第二个模拟器。 在B和C,127.0.0.1指的是模拟系统自身的环回接口,但10.0.2.2是指A的环回接口(又名A:127.0.0.1,指向PC机)。 10.0.2.15指的是模拟系统自身的网络地址。
比方说,我们要运行在B服务器在端口5000监听 即 10.0.2.15:5000 -在B的控制台,设置一个tcp重定向 redir add tcp:5000:5000 - 使在C客户端连接到tcp:10.0.2.2:5000 -即可访问到B的5000端口。
因为“redir加上”这个工程创建从一个重定向:127.0.0.1:5000到B:10.0.2.15:5000
那么C连接到B:10.0.2.2:5000这已经重定向到:127.0.0.1:5000都到B:10.0.2.15:5000
1 首先实现的是android模拟器终端中重定向(是在cmd下面)
步骤 1.打开两个模拟终端 adb devices (5554 5556)然后telnet 上5554(5554作为服务器端,5556作为客户端),命令telnet localhost 5554 成功后会有个啥子哦Ok的提示,然后就是端口的重定向,命令 redir add tcp:8000:7000(这一步特别要注意8000对应着客户端的new Socket(“10.0.2.2”,8000),7000对于这服务器端的SERVERPORT,即ServerSocket serverSocket = new ServerSocket(SERVERPORT),这里千万不能搞反 ,我就是搞反了 话了我一上午调试时间 悲催啊);
步骤 2。 这里重定向就完成了,可用命令redir list 查询重定向的端口,用redir del tcp:8000 删除刚才重定向的端口,可以关掉这个窗口了 。ps: 前面定义的重定向如果没有删除的话 将会一直存在 redir list 可以查询
2 代码:(是在网上找的,自己修改了哈,没学过java的搞android 伤的起?)
服务器端:
package com.android.study;
import android.app.Activity;
import android.os.Bundle;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
public static final String SERVERIP = "10.0.2.15";//这个地址其实没有用到
public static final int SERVERPORT = 5000; //注意这里和上面重定向的配置是有关系的。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (true) {
System.out.println("hell");
Socket client = serverSocket.accept();
System.out.println("hell2");
System.out.println("S: Receiving.../n"+client.getInetAddress());
client.getInetAddress();
}
}catch(Exception e) {
System.out.println("S: Error");
e.printStackTrace();
}
}
}
客户端:
package com.socket.client;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class main extends Activity implements OnClickListener{
/** Called when the activity is first created. */
//定义声明需要用到的UI元素
private EditText edtmsgcontent;
private Button btnSend;
private String ip="10.0.2.2";
private int port=8000;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
InitView();
}
private void InitView()
{
//显示主界面
setContentView(R.layout.main);
//通过id获取ui元素对象
edtmsgcontent=(EditText)findViewById(R.id.msgcontent);
btnSend=(Button)findViewById(R.id.btnsend);
//为btnsend设置点击事件
btnSend.setOnClickListener(this);
}
public void onClick(View bt)
{
try
{
String msg=edtmsgcontent.getText().toString();
if(!TextUtils.isEmpty(msg))
SendMsg(ip,port,msg);
else
{
Toast.makeText(this,"请先输入要发送的内容", Toast.LENGTH_LONG);
edtmsgcontent.requestFocus();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void SendMsg(String ip,int port,String msg)
throws UnknownHostException, IOException
{
try
{
Socket socket=null;
socket=new Socket(ip,port);
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write(msg);
writer.flush();
writer.close();
socket.close();
}
catch(UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
工程在我的115网盘