参考文章:http://blog.csdn.net/highram/article/details/6577465
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网盘