zoukankan      html  css  js  c++  java
  • Android网络编程之Socket

     Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器。有两种传输模式:

    1)、面向连接的传输:基于TCP协议,可靠性高,但效率低;

    2)、面向无连接的传输:基于UDP协议,可靠性低,但效率高;

            Android中,直接采用Socket通信应该是我们遇到的最低级的网络运用。尽管已经作了很大程度的抽象,但是纯粹的Socket通信,仍然给开发者留下很多细节需要处理,尤其在服务器端,开发者需要处理多线程以及数据缓冲等的设计问题。相对而言,处于更高抽象层的HTTP等,已经对Socket通信中需要处理的技术细节进行了很好的封装,开发者无须关心,因此,HTTP在网络开发中通常具有决定性的优势。

            Android在其核心库的java包中,提供了用于客户端的Socket class和用于服务器端的ServerSocket class,分别位于$SOURCE/libcore/luni/src/main/java/java/net/Socket.java和$SOURCE/libcore/luni/src/main/java/java/net/ServerSocket.java文件中。分析两个class的源码,可以看出封装考虑的很全面,只构造方法一向每个class都考虑了很多种使用情况。由于本人只是初学者,很多理解的不深入,这里只抛砖引玉的对两个class的构造方法分别介绍一种,就是我下面的程序中用到的:

    Socket(String dstName, int dstPort):创建一个以流的方式(基于TCP协议)连接到目标机(这里可以理解为服务器)的客户端Socket;dstName是目标机的IP地址,dstPort是要连接的目标机的端  口号。这里要注意对端口的理解,它不能理解为物理上的一个接口,而是对计算机中一块特殊内存区域的形象表述。

    ServerSocket(int aport):创建一个绑定到本机指定端口的服务端Socket;aport就是指定的本机端口。与上述客户端Socket对应,通过TCP连接时,ServerSocket创建后需要在aport端口上进行监听,等待客户端的连接。

            上面所写都是些背景知识,下面对本人的编程实践进行详细说明。

    1、功能描述

         1)、简单的基于Socket的数据通信;

         2)、采用TCP方式连接;

         3)、采用C/S结构,但服务端只支持一个连接;

         4)、客户端能够向服务端发送数据,并显示服务端的返回信息;

         5)、服务端能够接收客户端的数据,并将收到的数据以特定的方式返回给客户端;

    2、程序实现思路

        1)、服务端:设计为在后台执行的service,用一个独立的线程来处理客户端的连接请求、数据接收和返回。为了启动该service,编写个简单的Activity。

        2)、客户端:设计为一个Activity,界面由三部分组成:显示服务端返回信息的文本区域(一个文本框);进行数据输入的编辑区域(一个编辑框);以及触发连接请求并执行数据发送的触发区域(一个按钮)。

    3、服务端源程序

        1)、Activity文件SocketServerDemo.java

    [java] view plaincopy
     
     
    1. package com.android.sample.SocketServerDemo;  
    2.   
    3. import android.app.Activity;  
    4. import android.content.Intent;  
    5. import android.os.Bundle;  
    6.   
    7. public class SocketServerDemo extends Activity{  
    8.   
    9.     @Override  
    10.     protected void onCreate(Bundle savedInstanceState) {  
    11.         // TODO Auto-generated method stub  
    12.         super.onCreate(savedInstanceState);  
    13.           
    14.         setContentView(R.layout.main);  
    15.           
    16.         System.out.println("begin start service");   
    17.         this.startService(new Intent(this, SocketService.class));  
    18.     }  
    19.   
    20.     @Override  
    21.     protected void onDestroy() {  
    22.         // TODO Auto-generated method stub  
    23.         super.onDestroy();  
    24.           
    25.         this.stopService(new Intent(this, SocketService.class));  
    26.     }  
    27. }  

        2)、service文件SocketService.java

    [java] view plaincopy
     
     
    1. package com.android.sample.SocketServerDemo;  
    2.   
    3. import java.io.BufferedReader;  
    4. import java.io.BufferedWriter;  
    5. import java.io.IOException;  
    6. import java.io.InputStreamReader;  
    7. import java.io.OutputStreamWriter;  
    8. import java.io.PrintWriter;  
    9. import java.net.ServerSocket;  
    10. import java.net.Socket;  
    11.   
    12. import android.app.Service;  
    13. import android.content.Intent;  
    14. import android.os.IBinder;  
    15.   
    16. public class SocketService extends Service{  
    17.     Thread mServiceThread;  
    18.       
    19.     Socket client;  
    20.       
    21.     @Override  
    22.     public IBinder onBind(Intent intent) {  
    23.         // TODO Auto-generated method stub  
    24.         return null;  
    25.     }  
    26.   
    27.     @Override  
    28.     public void onCreate() {  
    29.         // TODO Auto-generated method stub  
    30.         super.onCreate();  
    31.           
    32.         mServiceThread = new Thread(new SocketServerThread());  
    33.     }  
    34.   
    35.     @Override  
    36.     public void onStart(Intent intent, int startId) {  
    37.         // TODO Auto-generated method stub  
    38.         super.onStart(intent, startId);  
    39.           
    40.         mServiceThread.start();  
    41.     }  
    42.   
    43.     @Override  
    44.     public void onDestroy() {  
    45.         // TODO Auto-generated method stub  
    46.         super.onDestroy();  
    47.     }  
    48.   
    49.     public class SocketServerThread extends Thread {  
    50.         private static final int PORT = 54321;  
    51.           
    52.         private SocketServerThread(){  
    53.         }  
    54.           
    55.         @Override  
    56.         public void run() {  
    57.             try {  
    58.                 ServerSocket server = new ServerSocket(PORT);  
    59.                   
    60.                 while(true){  
    61.                     System.out.println("begin client connected");  
    62.                     client = server.accept();  
    63.                     System.out.println("client connected");  
    64.                       
    65.                     BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));  
    66.                     System.out.println("read from client:");  
    67.                       
    68.                     String textLine = reader.readLine();  
    69.                     if(textLine.equalsIgnoreCase("EXIT")){  
    70.                         System.out.println("EXIT invoked, closing client");  
    71.                         break;  
    72.                     }  
    73.   
    74.                     System.out.println(textLine);  
    75.                       
    76.                     PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())));  
    77.                       
    78.                     writer.println("ECHO from server: " + textLine);  
    79.                     writer.flush();  
    80.                       
    81.                     writer.close();  
    82.                     reader.close();  
    83.                 }                             
    84.             } catch (IOException e) {  
    85.                 // TODO Auto-generated catch block  
    86.                 System.err.println(e);  
    87.             }     
    88.         }  
    89.           
    90.     }  
    91. }  

        3)、AndroidManifest.xml文件,因为需要在其中添加service和网络访问权限,这里一并贴出

    [html] view plaincopy
     
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.       package="com.android.sample.SocketServerDemo"  
    4.       android:versionCode="1"  
    5.       android:versionName="1.0">  
    6.     <uses-sdk android:minSdkVersion="9" />  
    7.   
    8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
    9.         <activity android:name=".ScreenCastServer"  
    10.                   android:label="@string/app_name">  
    11.             <intent-filter>  
    12.                 <action android:name="android.intent.action.MAIN" />  
    13.                 <category android:name="android.intent.category.LAUNCHER" />  
    14.             </intent-filter>  
    15.         </activity>  
    16.           
    17.         <service android:name="com.android.sample.SocketServerDemo.SocketService">  
    18.         </service>  
    19.   
    20.     </application>  
    21.       
    22.     <uses-permission android:name="android.permission.INTERNET"/>  
    23. </manifest>  

    4、客户端程序

        1)、布局文件main.xml

    [html] view plaincopy
     
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:orientation="vertical"  
    4.     android:layout_width="fill_parent"  
    5.     android:layout_height="fill_parent"  
    6.     >  
    7.     <TextView  
    8.         android:id="@+id/receive_msg"   
    9.         android:layout_width="fill_parent"   
    10.         android:layout_height="wrap_content"   
    11.         />  
    12.           
    13.     <EditText  
    14.         android:id="@+id/edit_msg"  
    15.         android:layout_width="fill_parent"  
    16.         android:layout_height="wrap_content"  
    17.         />  
    18.       
    19.     <Button  
    20.         android:id="@+id/send_msg"  
    21.         android:layout_width="wrap_content"  
    22.         android:layout_height="wrap_content"  
    23.         android:text="send"  
    24.         />  
    25. </LinearLayout>  

        2)、Activity文件SocketClientDemo.java

    [java] view plaincopy
     
     
    1. package com.android.sample.SocketClientDemo;  
    2.   
    3. import java.io.BufferedReader;  
    4. import java.io.BufferedWriter;  
    5. import java.io.IOException;  
    6. import java.io.InputStreamReader;  
    7. import java.io.OutputStreamWriter;  
    8. import java.io.PrintWriter;  
    9. import java.net.Socket;  
    10. import java.net.UnknownHostException;  
    11.   
    12. import android.app.Activity;  
    13. import android.os.Bundle;  
    14. import android.view.View;  
    15. import android.view.View.OnClickListener;  
    16. import android.widget.Button;  
    17. import android.widget.EditText;  
    18. import android.widget.TextView;  
    19.   
    20. public class SocketClientDemo extends Activity {  
    21.     private static final String SERVERIP = "192.168.1.68";  
    22.     private static final int SERVERPORT = 54321;  
    23.       
    24.     TextView mMsgRev;  
    25.     EditText mMsgEdit;  
    26.     Button   mMsgSendBtn;  
    27.       
    28.     String mSendMsg;  
    29.     String mReceivedMsg;  
    30.       
    31.     /** Called when the activity is first created. */  
    32.     @Override  
    33.     public void onCreate(Bundle savedInstanceState) {  
    34.         super.onCreate(savedInstanceState);  
    35.         setContentView(R.layout.main);  
    36.           
    37.         mMsgRev = (TextView)findViewById(R.id.receive_msg);  
    38.         mMsgEdit = (EditText)findViewById(R.id.edit_msg);  
    39.         mMsgSendBtn = (Button)findViewById(R.id.send_msg);  
    40.           
    41.         mMsgSendBtn.setOnClickListener(new OnClickListener(){  
    42.             @Override  
    43.             public void onClick(View v) {  
    44.                 Socket socket = null;  
    45.                 mSendMsg = mMsgEdit.getText().toString();  
    46.                   
    47.                 try {  
    48.                     socket = new Socket(SERVERIP, SERVERPORT);  
    49.                       
    50.                     PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));  
    51.                     writer.println(mSendMsg);  
    52.                     writer.flush();  
    53.                       
    54.                     BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));   
    55.                     mReceivedMsg = reader.readLine();  
    56.                     if(mReceivedMsg != null){  
    57.                         mMsgRev.setText(mReceivedMsg);  
    58.                     }else{  
    59.                         mMsgRev.setText("receive data error");  
    60.                     }  
    61.                       
    62.                     writer.close();  
    63.                     reader.close();  
    64.                     socket.close();  
    65.                 } catch (UnknownHostException e) {  
    66.                     // TODO Auto-generated catch block  
    67.                     e.printStackTrace();  
    68.                 } catch (IOException e) {  
    69.                     // TODO Auto-generated catch block  
    70.                     e.printStackTrace();  
    71.                 }  
    72.             }             
    73.         });  
    74.     }  
    75. }  

        3)、在AndroidManifest.xml中向服务器端的该文件一样,添加网络访问权限:<uses-permission android:name="android.permission.INTERNET"/>


    5、执行环境搭建

            服务端程序在开发板上执行,客户端程序在模拟器上执行,实现了基于Socket的数据收发。但是我这里只是进行了局域网内的通信,至于跨网络能不能行,目前条件不够,没法进行验证。

     转:http://blog.csdn.net/harry_helei/article/details/6638876

  • 相关阅读:
    mysql用户的管理
    openpyxl对excel实现字母与数字之间的转换
    字体识别
    python中os模块简单用法
    python合成语音
    python中openpyxl修改excel中字体及读取字体
    观察者模式-C#实现
    工厂模式-C#改良实现
    建造者模式-C#改良实现
    996 不是福气,努力也未必成功(转)
  • 原文地址:https://www.cnblogs.com/xijin-wu/p/5292595.html
Copyright © 2011-2022 走看看