一、概述

下面的实现中为了讲解的方便,并没有采用多线程的方法,因此通信过程中会阻塞UI线程,而且只涉及了单向通信(客户端-->服务器),完善的程序(多线程,双向通信)会在提高篇再讲解。

 

二、要求

     熟悉socket编程。

 

三、实现

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



[代码]xml代码:

 



<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical" >
 
     <EditText 
         android:id="@+id/edittext"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:hint="请输入要发送的内容"
         />
 
     <Button
         android:id="@+id/connectbutton"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="连接" 
         />
     
     <Button 
         android:id="@+id/sendbutton"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="发送"
         />
        
     
 </LinearLayout>



 

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



[代码]java代码:

 



package com.nan.client;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.Toast;
 
 
 public class MyClientActivity extends Activity 
 {
     private EditText mEditText = null;
     private Button connectButton = null;
     private Button sendButton = null;
     
     private Socket clientSocket = null;
     private OutputStream outStream = null;
     
     
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) 
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         
         mEditText = (EditText)this.findViewById(R.id.edittext);
         connectButton = (Button)this.findViewById(R.id.connectbutton);
         sendButton = (Button)this.findViewById(R.id.sendbutton);
         sendButton.setEnabled(false);      
         
         //连接按钮监听
         connectButton.setOnClickListener(new View.OnClickListener() 
         {
             
             @Override
             public void onClick(View v) 
             {
                 // TODO Auto-generated method stub
                 try 
                 {
                     //实例化对象并连接到服务器
                     clientSocket = new Socket("183.41.101.71",8888);
                 } 
                 catch (UnknownHostException e) 
                 {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 } 
                 catch (IOException e) 
                 {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 
                 displayToast("连接成功!");            
                 
                 connectButton.setEnabled(false);
                 sendButton.setEnabled(true);
             }
         });
         
         //发送数据按钮监听
         sendButton.setOnClickListener(new View.OnClickListener() 
         {
             
             @Override
             public void onClick(View v) 
             {
                 // TODO Auto-generated method stub
                 byte[] msgBuffer = null;
                 //获得EditTex的内容
                 String text = mEditText.getText().toString();
                 try {
                     //字符编码转换
                     msgBuffer = text.getBytes("GB2312");
                 } catch (UnsupportedEncodingException e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
                             
                 
                 try {
                     //获得Socket的输出流
                     outStream = clientSocket.getOutputStream();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }                                                    
                 
                 
                 try {
                     //发送数据
                     outStream.write(msgBuffer);
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 
                 displayToast("发送成功!");
             }
         });
               
         
     }
     
     //显示Toast函数
     private void displayToast(String s)
     {
         Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
     }
     
     
 }



 

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



[代码]xml代码:

 



<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical" >
 
     <TextView
         android:id="@+id/textview"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:textSize="15dip"
          
         />
 
 </LinearLayout>



 

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



[代码]java代码:

 



package com.nan.server;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.ServerSocket;
 import java.net.Socket;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.widget.TextView;
 
 
 public class MyServerActivity extends Activity 
 {
     private TextView mTextView = null;
     
     private InputStream mInputStream = null;
     private Socket clientSocket = null;
     private ServerSocket mServerSocket = null;
     
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) 
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         
         mTextView = (TextView)this.findViewById(R.id.textview);
         
         try {
             //实例化ServerSocket对象并设置端口号为8888
             mServerSocket = new ServerSocket(8888);
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         
         try {
             //等待客户端的连接(阻塞)
             clientSocket = mServerSocket.accept();
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         
         try {
             //获得socket的输入流
             mInputStream = clientSocket.getInputStream();
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         
         byte[] buf = new byte[512];  
         String str = null;
           
         try {
             //读取输入的数据(阻塞读)
             mInputStream.read(buf);
         } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         
         try {
             //字符编码转换
             str = new String(buf, "GB2312").trim();
         } catch (UnsupportedEncodingException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         //显示接收到的数据
         mTextView.setText("收到的数据:"+str);
             
     }
       
 }



 

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

 



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



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

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

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

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

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