zoukankan      html  css  js  c++  java
  • Android应用开发基础篇(12)Socket通信

    一、概述

          网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得socket编程是网络编程的基础。在进入正题之前,先介绍几点网络知识,一:socket编程有分TCP和UDP两种,TCP是基于连接的,而UDP是无连接的;二:一个TCP连接包括了输入和输出两条独立的路径;三:服务器必须先运行然后客户端才能与它进行通信。四:客户端与服务器所使用的编码方式要相同,否则会出现乱码。下面的实现中为了讲解的方便,并没有采用多线程的方法,因此通信过程中会阻塞UI线程,而且只涉及了单向通信(客户端-->服务器),完善的程序(多线程,双向通信)会在提高篇再讲解。


    二、要求

         熟悉socket编程。


    三、实现

         新建工程MyClient,修改/res/layout/main.xml文件,在里面添加一个EditText和两个Button,完整的main.xml文件如下:

     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:layout_width="fill_parent"
    4 android:layout_height="fill_parent"
    5 android:orientation="vertical" >
    6
    7 <EditText
    8 android:id="@+id/edittext"
    9 android:layout_width="fill_parent"
    10 android:layout_height="wrap_content"
    11 android:hint="请输入要发送的内容"
    12 />
    13
    14 <Button
    15 android:id="@+id/connectbutton"
    16 android:layout_width="fill_parent"
    17 android:layout_height="wrap_content"
    18 android:text="连接"
    19 />
    20
    21 <Button
    22 android:id="@+id/sendbutton"
    23 android:layout_width="fill_parent"
    24 android:layout_height="wrap_content"
    25 android:text="发送"
    26 />
    27
    28
    29 </LinearLayout>

    接着,修改MyClientActivity.java文件,定义一个socket对象和一个OutputStream对象(用于发送数据),完整的内容如下:

      1 package com.nan.client;
    2
    3 import java.io.IOException;
    4 import java.io.OutputStream;
    5 import java.io.UnsupportedEncodingException;
    6 import java.net.Socket;
    7 import java.net.UnknownHostException;
    8
    9 import android.app.Activity;
    10 import android.os.Bundle;
    11 import android.view.View;
    12 import android.widget.Button;
    13 import android.widget.EditText;
    14 import android.widget.Toast;
    15
    16
    17 public class MyClientActivity extends Activity
    18 {
    19 private EditText mEditText = null;
    20 private Button connectButton = null;
    21 private Button sendButton = null;
    22
    23 private Socket clientSocket = null;
    24 private OutputStream outStream = null;
    25
    26
    27 /** Called when the activity is first created. */
    28 @Override
    29 public void onCreate(Bundle savedInstanceState)
    30 {
    31 super.onCreate(savedInstanceState);
    32 setContentView(R.layout.main);
    33
    34 mEditText = (EditText)this.findViewById(R.id.edittext);
    35 connectButton = (Button)this.findViewById(R.id.connectbutton);
    36 sendButton = (Button)this.findViewById(R.id.sendbutton);
    37 sendButton.setEnabled(false);
    38
    39 //连接按钮监听
    40 connectButton.setOnClickListener(new View.OnClickListener()
    41 {
    42
    43 @Override
    44 public void onClick(View v)
    45 {
    46 // TODO Auto-generated method stub
    47 try
    48 {
    49 //实例化对象并连接到服务器
    50 clientSocket = new Socket("183.41.101.71",8888);
    51 }
    52 catch (UnknownHostException e)
    53 {
    54 // TODO Auto-generated catch block
    55 e.printStackTrace();
    56 }
    57 catch (IOException e)
    58 {
    59 // TODO Auto-generated catch block
    60 e.printStackTrace();
    61 }
    62
    63 displayToast("连接成功!");
    64
    65 connectButton.setEnabled(false);
    66 sendButton.setEnabled(true);
    67 }
    68 });
    69
    70 //发送数据按钮监听
    71 sendButton.setOnClickListener(new View.OnClickListener()
    72 {
    73
    74 @Override
    75 public void onClick(View v)
    76 {
    77 // TODO Auto-generated method stub
    78 byte[] msgBuffer = null;
    79 //获得EditTex的内容
    80 String text = mEditText.getText().toString();
    81 try {
    82 //字符编码转换
    83 msgBuffer = text.getBytes("GB2312");
    84 } catch (UnsupportedEncodingException e1) {
    85 // TODO Auto-generated catch block
    86 e1.printStackTrace();
    87 }
    88
    89
    90 try {
    91 //获得Socket的输出流
    92 outStream = clientSocket.getOutputStream();
    93 } catch (IOException e) {
    94 // TODO Auto-generated catch block
    95 e.printStackTrace();
    96 }
    97
    98
    99 try {
    100 //发送数据
    101 outStream.write(msgBuffer);
    102 } catch (IOException e) {
    103 // TODO Auto-generated catch block
    104 e.printStackTrace();
    105 }
    106
    107 displayToast("发送成功!");
    108 }
    109 });
    110
    111
    112 }
    113
    114 //显示Toast函数
    115 private void displayToast(String s)
    116 {
    117 Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
    118 }
    119
    120
    121 }

    接着,新建工程MyServer,同样修改/res/layout/main.xml文件,如下:

     1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:layout_width="fill_parent"
    4 android:layout_height="fill_parent"
    5 android:orientation="vertical" >
    6
    7 <TextView
    8 android:id="@+id/textview"
    9 android:layout_width="fill_parent"
    10 android:layout_height="wrap_content"
    11 android:textSize="15dip"
    12
    13 />
    14
    15 </LinearLayout>

    修改MyServerActivity.java文件,比较简单,代码中有详细注释,如下:

     1 package com.nan.server;
    2
    3 import java.io.IOException;
    4 import java.io.InputStream;
    5 import java.io.UnsupportedEncodingException;
    6 import java.net.ServerSocket;
    7 import java.net.Socket;
    8
    9 import android.app.Activity;
    10 import android.os.Bundle;
    11 import android.widget.TextView;
    12
    13
    14 public class MyServerActivity extends Activity
    15 {
    16 private TextView mTextView = null;
    17
    18 private InputStream mInputStream = null;
    19 private Socket clientSocket = null;
    20 private ServerSocket mServerSocket = null;
    21
    22 /** Called when the activity is first created. */
    23 @Override
    24 public void onCreate(Bundle savedInstanceState)
    25 {
    26 super.onCreate(savedInstanceState);
    27 setContentView(R.layout.main);
    28
    29 mTextView = (TextView)this.findViewById(R.id.textview);
    30
    31 try {
    32 //实例化ServerSocket对象并设置端口号为8888
    33 mServerSocket = new ServerSocket(8888);
    34 } catch (IOException e) {
    35 // TODO Auto-generated catch block
    36 e.printStackTrace();
    37 }
    38
    39 try {
    40 //等待客户端的连接(阻塞)
    41 clientSocket = mServerSocket.accept();
    42 } catch (IOException e) {
    43 // TODO Auto-generated catch block
    44 e.printStackTrace();
    45 }
    46
    47 try {
    48 //获得socket的输入流
    49 mInputStream = clientSocket.getInputStream();
    50 } catch (IOException e) {
    51 // TODO Auto-generated catch block
    52 e.printStackTrace();
    53 }
    54
    55 byte[] buf = new byte[512];
    56 String str = null;
    57
    58 try {
    59 //读取输入的数据(阻塞读)
    60 mInputStream.read(buf);
    61 } catch (IOException e) {
    62 // TODO Auto-generated catch block
    63 e.printStackTrace();
    64 }
    65
    66 try {
    67 //字符编码转换
    68 str = new String(buf, "GB2312").trim();
    69 } catch (UnsupportedEncodingException e) {
    70 // TODO Auto-generated catch block
    71 e.printStackTrace();
    72 }
    73 //显示接收到的数据
    74 mTextView.setText("收到的数据:"+str);
    75
    76 }
    77
    78 }

    最后在两个工程的AndroidMainfest.xml文件中都加入权限:

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

    到这里,客户端和服务器的程序都写好了,在模拟器上运行客户端程序:

    在真机上运行服务器程序:

    接着,点击客户端“连接”按钮,输入一些内容再点击“发送”按钮:

    此时服务器端的情况如下:

    可见成功接收了客户端发送过来的数据。




  • 相关阅读:
    【矩阵】
    关于集合的思路
    TSQL生成Combguid
    ServiceLocator是反模式
    使用表达式树创建对象
    TeamCity配置笔记
    AutoMapper映射ExpressionTree
    Automapper扩展方法
    Cache&Session Viewer
    Orchard源码:Logging
  • 原文地址:https://www.cnblogs.com/lknlfy/p/2378669.html
Copyright © 2011-2022 走看看