现代生活中,我们的移动设备离不开网络,我们的APP也经常需要连接到网络,所以现在,在这里完成一个简单的Socket通信程序,实现Android客户端与本地的服务器通信。

  关于网络通信的知识,互联网上有很多相关的讲解,这里就不进行详细的讲解了,直接就代码进行讲解。

  需要注意的是,Android应用Socket通信时,有几点要求必须得遵守:

1. andriod客户端添加网络访问权限

  在写客户端程序时,必须要在Manifest.xml文件中添加网络访问权限,当然如果你愿意,也可以加上对WiFi状态进行查看的权限。

<uses-permission  android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

  当然,你不加这两条网络访问权限程序并不会抛出任何的异常,运行起来也并看不出有什么毛病,但是,程序结果肯定不对。之前用真机做过测试,不加这两条权限,在同一局域网内,手机是可以连接到服务器上的,只不过,在服务器端,得到连接的IP地址和服务器的IP是一样的,这可能只是偶然情况。
  如果不加这两条权限,客户端和服务器是不能进行通信的。

2.对Socket的操作放在非UI线程内进行

  在Android应用中,为了保证APP的用户体验,必须对用户的操作尽可能快的做出响应,因此在以前的Android版本中,不建议将耗时的操作放在UI线程中。到Android3.0之后的版本,则是更进一步做了限制,在非UI线程中禁止操作UI,在UI线程中禁止做响应时间长的操作,如联网操作。

   如果在UI线程中进行联网操作的话,会抛出NetworkOnMainThread异常,因此,Socket操作必须放在子线程内进行。

3.要使用正确的IP地址和端口号

  Socket通信,必须指定IP地址和端口号,需要注意的是端口号不能随便分配。

  端口号的范围是0~65535,1024一下的端口被系统分给了一些服务,慎用(建议不要使用这段范围的端口),还有一些端口被分配给了特定的服务,比如http的8080端口,其他的端口应该都没有太大问题。

  在cmd窗口执行netstat -ano命令可以看到所有端口的使用情况。

  对于IP地址,有两种情况要注意。

  如果使用真机进行调试,手机必须和电脑在同一个网段内,可以连接同一个wifi,也可以用电脑开一个无线热点,手机连上热点就行,无论哪种方式,要求手机和电脑都能上网,否则,也是无法通信的。然后,程序中新建一个Socket的时候,使用电脑的IP就可以。

  如果使用模拟器进行调试,就不必考虑那么多情况了。新建Socket时,IP地址要使用10.0.2.2,这是系统为模拟器专门分配的,不能使用127.0.0.1.至于网上说的很多,PC和模拟器通信时,要使用端口重定向的问题,我在测试的时候,没有进行端口重定向,也可以实现PC向模拟器发数据。

  好了,废话说完了,直接上代码吧。

客户端:
  在一个EditText中输入一些字符,点击Button,把这些字符发送到服务器,服务器在收到这些数据后,在将这些数据返回给客户端。(xml文件比较简单,这里就不写了)

public class MainActivity extends Activity {//IP地址和端口号public static String IP_ADDRESS = "10.0.2.2";public static int PORT = 2346;//三个控件EditText text = null;Button connect = null;TextView info = null;//handlerHandler handler = null;Socket soc = null;DataOutputStream dos = null;DataInputStream dis = null;String messageRecv = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text = (EditText)findViewById(R.id.editText);connect = (Button)findViewById(R.id.buttonConnection);connect.setOnClickListener(new ConnectionListener());info = (TextView)findViewById(R.id.info);handler = new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);Bundle b = msg.getData();  //获取消息中的Bundle对象String str = b.getString("data");  //获取键为data的字符串的值info.append(str);}}};}//Button的Listenerclass ConnectionListener implements OnClickListener{@Overridepublic void onClick(View v){new ConnectionThread(text.getText().toString()).start();}}//新建一个子线程,实现socket通信class ConnectionThread extends Thread{String message = null;public ConnectionThread(String msg){message = msg;}@Overridepublic void run(){if(soc == null){try {//Log.d("socket","new socket");soc = new Socket(IP_ADDRESS, PORT);//获取socket的输入输出流dis = new DataInputStream(soc.getInputStream());dos = new DataOutputStream(soc.getOutputStream());}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}try{dos.writeUTF(message);dos.flush();    messageRecv = dis.readUTF();//如果没有收到数据,会阻塞Message msg = new Message();Bundle b = new Bundle();b.putString("data", messageRecv);msg.setData(b);handler.sendMessage(msg);}catch(){// TODO Auto-generated catch blocke.printStackTrace();}}}

服务器端
  和客户端建立连接以后,在收到的字符串前加一个“received:”,然后返回给客户端

public class Server {ServerSocket serverSocket = null;public final int port = 2346;public Server(){//输出服务器的IP地址try {InetAddress addr = InetAddress.getLocalHost();System.out.println("local host:"+addr);serverSocket = new ServerSocket(port);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void startService(){try {Socket socket = null;System.out.println("waiting...");//等待连接,每建立一个连接,就新建一个线程while(true){                socket = serverSocket.accept();//等待一个客户端的连接,在连接之前,此方法是阻塞的System.out.println("connect to"+socket.getInetAddress()+":"+socket.getLocalPort());new ConnectThread(socket).start();}} catch (IOException e) {// TODO Auto-generated catch blockSystem.out.println("IOException");e.printStackTrace();}}//向客户端发送信息class ConnectThread extends Thread{Socket socket = null;public ConnectThread(Socket socket){    super();this.socket = socket;}@Overridepublic void run(){try {DataInputStream dis = new DataInputStream(socket.getInputStream());DataOutputStream dos = new DataOutputStream(socket.getOutputStream());while(true){String msgRecv = dis.readUTF();System.out.println("msg from client:"+msgRecv);dos.writeUTF("received:"+msgRecv);dos.flush();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static void main(String[] args) {// TODO Auto-generated method stubnew Server().startService();}}

TCP协议,百度百科
UDP协议,百度百科

Android客户端与本地服务器Socket通信相关推荐

  1. Android客户端,PC服务器,Socket连接所遇到的问题

    这两天在编写 Socket客户端,服务器Demo时的总结: 1.客户端与服务器的形式:Android手机客户端,PC搭建Socket服务器,采用的是Apache-mina开源框架(异步连接框架). 2 ...

  2. Android客户端与PC服务器实现Socket通信

    Android终端持续扫描AP信息并发送给服务器端的实现.首先基于TCP协议在Android终端和PC两端之间形成网络虚拟链路.使用ServerSocket创建TCP服务器端,然后在Android客户 ...

  3. unity android服务器端,【深圳Unity3D培训】 Android客户端与PC服务器实现Socket通信

    [深圳Unity3D培训] Android客户端与PC服务器实现Socket通信 Android终端连续扫描AP信息并发送给服务器端的完成.起首基于TCP协定在Android终端和PC两头之间构成收集 ...

  4. Android客户端与PC服务器通过socket进行交互实例

    一直以来对Android socket通信都很模糊,今天终于研究了一个网上的例子,自己又修改了下,算是对Android socket通信有点了解了. 下面是具体的代码,说明都在注释中了.需要注意的是, ...

  5. Android java和C的Socket通信demo(可用)

    原址 关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过<android使用socket使底层和framework通信>这篇文章,美中不足的是作 ...

  6. Android客户端与PC服务器实现Socket通信(wifi)

    转载自:http://www.cnblogs.com/dwayne/archive/2012/05/22/Android_pc_wifi_socket.html 本文介绍Android终端持续扫描AP ...

  7. unity3d Android客户端与PC服务器实现Socket通信(wifi)

    本文介绍Android终端持续扫描AP信息并发送给服务器端的实现.首先基于TCP协议在Android终端和PC两端之间形成网络虚拟链路.使用ServerSocket创建TCP服务器端,然后在Andro ...

  8. Android客户端与PC服务器如何实现Socket通信

    转载链接←←←← 本文介绍Android终端持续扫描AP信息并发送给服务器端的实现.首先基于TCP协议在Android终端和PC两端之间形成网络虚拟链路.使用ServerSocket创建TCP服务器端 ...

  9. unity android服务器端,[转载收藏]unity3d Android客户端与PC服务器实现Socket通信(wifi)...

    本文介绍Android终端持续扫描AP信息并发送给服务器端的实现.首先基于TCP协议在Android终端和PC两端之间形成网络虚拟链路.使用ServerSocket创建TCP服务器端,然后在Andro ...

最新文章

  1. 43 | 发挥人的潜能:探索式测试
  2. 网站开发常用jQuery插件总结(15)上传插件blueimp
  3. 大快搜索城市运河大数据政务管理平台案例解读
  4. ubuntu安装使用ffmpeg
  5. 华为eNSP模拟器学习(一)
  6. git和gitlab安装
  7. Sublime Text 2/3如何支持中文GBK编码(亲测实现)
  8. Atitit.web的自动化操作与信息抓取 attilax总结
  9. 快速阅读《构建之法》——构建之法阅读笔记01
  10. Excel文件输出到浏览器
  11. 测试电脑整机功耗软件,有什么好的测电脑整机功耗的软件吗?
  12. win7连接远程服务器特别慢,主编告诉你win7远程桌面连接速度慢的完全解决教程...
  13. 关于记忆的10个惊人事实
  14. 流媒体协议RTP、RTCP、H264详解
  15. 融合记忆法的程序员高效自学方法
  16. Unity 水波纹Shader
  17. JQueryUI自动补全 搜索提示实践
  18. 中美将改头换面融为一体----中美“一体化”
  19. 6:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转
  20. 2018麦考林杂志计算机科学,2018年加拿大大学麦考林杂志排名发布,快来围观你喜欢的学校排名有什么变动没?...

热门文章

  1. CSS margin 重叠(margin collapse)
  2. Java在ACM中的使用
  3. 使用函数实现字符串复制
  4. 威马汽车闫枫:造车新赛道的互联网思维
  5. Python 获取视频时长(附代码) | Python工具
  6. 大牧絮叨设计模式:建造者模式
  7. php分库分表技术,谈谈关于分库分表的方案
  8. TOC制约理论之高德拉特三问和6种思考工具
  9. 创作者经济:「正统性危机」之下的变革之路
  10. 用代理服务器实现Drcom共享上网