android--基于android平台socket服务器端实例

socket相关知识

1.什么是socket 
  所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 以J2SDK-1.3为例,Socket和ServerSocket类库位于java .net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。

重要的Socket API 
  重要的Socket API:java .net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。

  Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。 
  getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。 
  getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。 注意:其中getInputStream和getOutputStream方法均可能会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。

2.如何开发一个Server-Client模型的程序 
  开发原理: 
  服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。 
  客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。 
  Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。 Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

常用的Socket类型

  有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。 Socket建立为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket函数原型为:int socket(int domain, int type, int protocol);domain指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值0。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。

-UDP协议和TCP协议

    UDP协议和TCP协议是互联网使用最广的两种协议都是基于IP的协议。第一个区别是UDP协议是一个不太靠谱的协议,UDP协议把数据都打成数据包,数据包上自带通讯地址,也就是说我要把这个数据包发送到网络上的哪一个地址,通过网络把这个数据包发送出去,至于这个数据包是否发送到目的地,是否服务器端接收到了这个数据包,这个协议并不保证,就像中国的邮政,你是把信寄出去了,但是邮政系统不保证对方能收到你寄送的信。TCP发送数据的时候要求接收方接收到数据之后给一个回应,也就是你是否收到了,TCP可靠一些,当我们发送一些比较重要的数据的时候一般都使用TCP协议。另外一个区别是UDP协议发送的一个数据包它的容量是有限的,而TCP协议则没有这样一个限制。并不是说UDP协议一定就不如TCP协议,在不同的领域有不同是使用,UDP协议好处是速度相对快些。TCP协议相对慢些。

    -Socket通讯流程

    应用程序通过“套接字”也就是Socket可以选择这两种协议当中的一种,你可以选择用UDP发送数据,也可以选择用TCP发送数据,数据发送出去通过“通信信道”也就是IP的基础网络,来到服务器端(接收端),就可以接收到数据了。发送数据的时候用UDP协议,接收的时候也要用UDP协议,发送数据的时候用TCP协议,接收的时候也要用TCP协议,在发送的时候指定接收端的IP地址和端口号就可以了,究竟数据包或数据是如何发送的,框架已经帮我们封装好了,我们不去关心它了。

一:TCP协议通讯模型    1:工作流程     

    首先有两部分客户端和服务器端,客户端需要Socket这个类的对象,而服务器端需要ServerSocket这个类的对象,由客户端Socket发送一个请求,服务器端的ServerSocket在计算机的某一个端口号上进行监听,监听客户端发送的请求之后,那么客户端和服务器端的一个通讯通道就建立起来了,这时候呢既可以从客户端向服务器端发送数据,服务器端也可以给客户端相应的响应。在客户端发送数据的时候我们需要用到IO流里面的OutputStream,通过这个OutputStream把数据发送给服务器端,服务器端用InputStream来读取客户端当中用OutputStream所写入的数据。生活举例:就像双方男女朋友打电话一样,男孩(客户端)说话(数据)通过听筒发送到电话网络中去,当男孩说话的时候就相当于咱们这里的通过OutputStream向互联网中写入数据,而作为接听的这个女孩(服务器端)那么男孩(客户端)说的内容就是女孩(服务器端)听到的内容,那么就是说服务器端可以通过InputStream把客户端当中通过OutputStream所写入的数据给它读取出来,反之亦然,如果服务器端想向客户端发送数据,那么就使用OutputStream写出数据,在客户端通过InputStream把服务器端当中通过OutputStream所写入的数据给它读取出来。就像打电话一样,你说的就是我听的,你听的就是我说的。  二:通过基于TCP协议发送和读取数据

好了我们看看在Android中如何使用Socket的。

Android中使用Socket模型 

服务器端:

复制代码

  1. package com;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.io.OutputStreamWriter;
  7. import java.io.PrintWriter;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import java.util.concurrent.ExecutorService;
  13. import java.util.concurrent.Executors;
  14. /**
  15. * com Server
  16. *
  17. * @author Aina.huang E-mail: [email protected]
  18. * @version 创建时间:2010 Jul 14, 2010 10:45:35 AM 类说明
  19. */
  20. public class Main {
  21. private static final int PORT = 9999;// 端口监听
  22. private List<Socket> mList = new ArrayList<Socket>();// 存放客户端socket
  23. private ServerSocket server = null;
  24. private ExecutorService mExecutorService = null;// 线程池
  25. /**
  26. * @param args
  27. */
  28. public static void main(String[] args) {
  29. // TODO Auto-generated method stub
  30. new Main();
  31. }
  32. public Main() {
  33. try {
  34. server = new ServerSocket(PORT);
  35. mExecutorService = Executors.newCachedThreadPool();// 创建一个线程池
  36. System.out.println("Server Start...");
  37. Socket client = null;
  38. while (true) {
  39. client = server.accept();
  40. mList.add(client);
  41. mExecutorService.execute(new Service(client));// 开启一个客户端线程.
  42. }
  43. } catch (Exception ex) {
  44. ex.printStackTrace();
  45. }
  46. }
  47. public class Service implements Runnable {
  48. private Socket socket;
  49. private BufferedReader in = null;
  50. private String msg = "";
  51. public Service(Socket socket) {
  52. this.socket = socket;
  53. try {
  54. in = new BufferedReader(new InputStreamReader(socket
  55. .getInputStream()));
  56. msg = "user:" + this.socket.getInetAddress() + " come total:"
  57. + mList.size();
  58. this.sendmsg();
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. public void run() {
  64. // TODO Auto-generated method stub
  65. try {
  66. while (true) {
  67. if ((msg = in.readLine()) != null) {
  68. if (msg.equals("exit")) {
  69. System.out.println("sssssssssss");
  70. mList.remove(socket);
  71. in.close();
  72. msg = "user:" + socket.getInetAddress()
  73. + " exit total:" + mList.size();
  74. socket.close();
  75. this.sendmsg();
  76. break;
  77. } else {
  78. msg = socket.getInetAddress() + " : " + msg;
  79. this.sendmsg();
  80. }
  81. }
  82. }
  83. } catch (Exception ex) {
  84. System.out.println("server 读取数据异常");
  85. ex.printStackTrace();
  86. }
  87. }
  88. /**
  89. * 发送消息给所有客户端
  90. */
  91. public void sendmsg() {
  92. System.out.println(msg);
  93. int num = mList.size();
  94. for (int i = 0; i < num; i++) {
  95. Socket mSocket = mList.get(i);
  96. PrintWriter pout = null;
  97. try {
  98. pout = new PrintWriter(new BufferedWriter(
  99. new OutputStreamWriter(mSocket.getOutputStream())),
  100. true);
  101. pout.println(msg);
  102. } catch (IOException e) {
  103. e.printStackTrace();
  104. }
  105. }
  106. }
  107. }
  108. }

接下来是客服端程序:

复制代码

  1. package com.Aina.Android;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. import java.io.PrintWriter;
  7. import java.net.Socket;
  8. import android.app.Activity;
  9. import android.app.AlertDialog;
  10. import android.content.DialogInterface;
  11. import android.os.Bundle;
  12. import android.os.Handler;
  13. import android.os.Message;
  14. import android.util.Log;
  15. import android.view.View;
  16. import android.widget.Button;
  17. import android.widget.EditText;
  18. import android.widget.TextView;
  19. public class Test extends Activity implements Runnable {
  20. /** Called when the activity is first created. */
  21. private TextView tv_msg = null;
  22. private EditText ed_msg = null;
  23. private Button btn_send = null;
  24. private Button btn_login = null;
  25. private static final String HOST = "192.168.0.132";
  26. private static final int PORT = 9999;
  27. private Socket socket = null;
  28. private BufferedReader in = null;
  29. private PrintWriter out = null;
  30. private String content = "";
  31. @Override
  32. public void onCreate(Bundle savedInstanceState) {
  33. super.onCreate(savedInstanceState);
  34. setContentView(R.layout.main);
  35. tv_msg = (TextView) this.findViewById(R.id.TextView);
  36. ed_msg = (EditText) this.findViewById(R.id.EditText01);
  37. btn_login = (Button) this.findViewById(R.id.Button01);
  38. btn_send = (Button) this.findViewById(R.id.Button02);
  39. try {
  40. socket = new Socket(HOST, PORT);
  41. in = new BufferedReader(new InputStreamReader(socket
  42. .getInputStream()));
  43. out = new PrintWriter(new BufferedWriter(
  44. new OutputStreamWriter(socket.getOutputStream())),
  45. true);
  46. } catch (Exception ex) {
  47. ex.printStackTrace();
  48. ShowDialog("登陆异常:" + ex.getMessage());
  49. }
  50. btn_send.setOnClickListener(new Button.OnClickListener() {
  51. public void onClick(View v) {
  52. // TODO Auto-generated method stub
  53. String msg = ed_msg.getText().toString();
  54. if (socket.isConnected()) {
  55. if (!socket.isOutputShutdown()) {
  56. out.println(msg);
  57. }
  58. }
  59. }
  60. });
  61. new Thread(this).start();
  62. }
  63. public void ShowDialog(String msg) {
  64. new AlertDialog.Builder(this).setTitle("提示").setMessage(msg)
  65. .setPositiveButton("OK", new DialogInterface.OnClickListener() {
  66. public void onClick(DialogInterface dialog, int which) {
  67. // TODO Auto-generated method stub
  68. }
  69. }).show();
  70. }
  71. public void run() {
  72. try {
  73. while (true) {
  74. if(socket.isConnected()){
  75. if(!socket.isInputShutdown()){
  76. if ((content = in.readLine()) != null) {
  77. Log.i("TAG", "++ "+content);
  78. content += "\n";
  79. mHandler.sendMessage(mHandler.obtainMessage());
  80. }else{
  81. }
  82. }
  83. }
  84. }
  85. } catch (Exception ex) {
  86. ex.printStackTrace();
  87. }
  88. }
  89. public Handler mHandler = new Handler() {
  90. public void handleMessage(Message msg) {
  91. super.handleMessage(msg);
  92. Log.i("TAG", "-- "+msg);
  93. tv_msg.setText(tv_msg.getText().toString() + content);
  94. }
  95. };
  96. }

接下来是XML文件布局。

复制代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical" android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <TextView android:id="@+id/TextView" android:singleLine="false"
  6. android:layout_width="fill_parent"
  7. android:layout_height="wrap_content" />
  8. <EditText android:hint="content" android:id="@+id/EditText01"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content">
  11. </EditText>
  12. <Button android:text="login" android:id="@+id/Button01"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content">
  15. </Button>
  16. <Button android:text="send" android:id="@+id/Button02"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content">
  19. </Button>
  20. </LinearLayout>

问题解决&处理

1 出现02-07 12:16:11.507: W/System.err(1173): java.net.BindException: Permission denied错误

按照如下方法解决,端口号取大于1024的。并且加上android.permission.INTERNET权限。

1)Either root your phone, modify the firmware, or don‘t bind to ports lower than 1024. That‘s a Linux thing more than an Android thing.

2)Try add permission android.permission.INTERNET it worked for me

2 使用客户端连接时,出现java.net.ConnectException: Connection refused错误

将与安卓模拟器通讯的ip地址改为10.0.0.2。错误取消。

时间: 2024-11-06 19:29:35

android--基于android平台socket服务器端实例的相关文章

基于Android平台的i-jetty网站智能农业监控系统

基于android平台i-jetty网站的智能农业监控系统 摘要:传统的监控系统,一般是基于PC的有线通信传输,其有很多不足之处,如功耗较高.布线成本高.难度大,适应性差,可扩展性不强,增加新的通信线路需要再次布线施工,而且维护起来也比较麻烦,一旦线路出问题,需要繁琐的检查.而嵌入式Web监控系统是基于物联网技术,其无线通信技术具有成本低廉.适应性强.扩展性强.信息安全.使用维护简单等优点. 智能农业中,种植大棚是通过大棚内安装温湿度以及光照传感器,来对农作物的环境参数进行实时采集,由Web监控

基于android的Socket通信

一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过建立sock

基于Android 平台简易即时通讯的研究与设计[转]

摘要:论文简单介绍Android 平台的特性,主要阐述了基于Android 平台简易即时通讯(IM)的作用和功能以及实现方法.(复杂的通讯如引入视频音频等可以考虑AnyChat SDK~)关键词:Android 平台:即时通讯 (本文中图表点击附件即可见) 1 Android 平台简介Android 是Google 公司于2007年11月5日推出的手机操作系统,经过2年多的发展,Android平台在智能移动领域占有不小的份额,由Google为首的40 多家移动通信领域的领军企业组成开放手机联盟(

android网络通信之socket教程实例汇总

一.socket基础1.Socket通讯机制(详细),如何将socket通信的客户端与服务器http://www.eoeandroid.com/thread-61727-1-1.html 2.Http和Socket区别http://www.eoeandroid.com/thread-96927-1-1.html 二.实例教程1.Android开发之socket通信 向PC机发信息 获取本机IPhttp://www.eoeandroid.com/thread-97477-1-1.html 2.PC

cocos2dx-2.X前后台切换分析,基于android平台

摘自网上的android生命周期图: cocos2dx-2.X前后台切换分析,基于android平台: 1.从后台进入前台 项目的activity一般继承自Cocos2dxActivity,看过activity生命周期的 都知道onCreate,onResume等方法,这些函数是activity生命周期中 最重要的函数,具体什么时候调用,可以查看相关资料. //刚进入游戏和游戏从后台回到前台会调用 @Override protected void onResume() { super.onRes

基于Android平台简易即时通讯的研究与设计

1 Android平台简介 Android是Google公司于2007年11月5日推出的手机操作系统,经过2年多的发展,Android平台在智能移动领域占有不小的份额,由Google为首的40多家移动通信领域的领军企业组成开放手机联盟(OHA).Google与运营商.设备制造商.开发商和其他第三方结成深层次的合作伙伴关系,希望通过建立标准化.开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统.正因如此,Android正在被越来越多的开发者和使用者所接受.近日,Google发言人Ant

基于Android平台的会议室管理系统具体设计说明书

会议室管理系统具体设计说明书 第一部分  引言 1.编写目的 本说明对会议室管理系统项目的各模块.页面.脚本分别进行了实现层面上的要求和说明. 软件开发小组的产品实现成员应该阅读和參考本说明进行代码的编写.測试. 1.2 背景 说明: A.软件系统的名称:会议室管理系统 B. 任务提出者:内蒙古大学计算机学院 开发人员:魏晓蕾 本项目将实现基于Android平台的会议室管理系统的原型部分,而且在该原型的基础上进行功能的扩展和需求的界定,终于完毕的版本号将在全国范围内推广使用. 提供会议室管理功能

Android串口通信(基于Tiny6410平台)

友善之臂的Android系统有他们自己编写的一个串口通信程序,网上没有找到他的源代码,而且界面操作不在一个界面,不是很方便,这里我自己写了一个粗糙点的串口通信程序. 同样这里还是调用友善之臂的friendlyarm-hardware.so库文件. 在Android工程文件下面加入com.friendlyarm.androidSDK包,在其下添加HardwareControler.java.下面我把我做的截图发上来. 主程序代码: package geekle.lab; import androi

基于Android、iOS平台的移动端车牌识别技术及实现车牌识别过程

近年来,随着移动行业的爆发式发展,手机配置不断提高,基于手机平台的信息采集.图像处理.数据传输等方面的研究也成为了热点,这使得基于手机平台上的车牌识别成为可能.传统的车牌识别系统一般都基于固定的桌面平台.图像采集不灵活,特别是对于交通管理部门来说,对违章车辆车牌的自动登记非常不便,因此基于Android.iOS平台的移动端车牌识别技术出现了. 那么如何实现车牌识别的呢,下面简单说说: 首先对现存的车牌识别算法进行了研究,在诸多算法中寻找到一种适合在Android.iOS平台上运行的算法.先通过智