转载:Android的网络应用 - 简单的C/S聊天室

原文:http://blog.csdn.net/wwj_748/article/details/7825111

Android的网络应用 - 简单的C/S聊天室

服务器端:提供两个类

创建ServerSocket监听的主类:MyServer.java

负责处理每个Socket通信的线程类:ServerThread.java

 

客户端:是一个Android应用程序

==>MultiThreadClient

界面提供两个文本框和一个发送按钮

Activity通过Handler来处理来自子线程的消息

客户端需要一个子线程负责读取来自网络的数据

 

项目效果:

 

服务器端代码:

MyServer.java

  1. import java.io.IOException;  
  2. import java.net.ServerSocket;  
  3. import java.net.Socket;  
  4. import java.util.ArrayList;  
  5.   
  6.   
  7. public class MyServer  
  8. {  
  9.     //定义保存所有Socket的ArrayList  
  10.     public static ArrayList<Socket> socketList   
  11.         = new ArrayList<Socket>();  
  12.     public static void main(String[] args)   
  13.         throws IOException  
  14.     {  
  15.         ServerSocket ss = new ServerSocket(8000);  
  16.         while(true)  
  17.         {  
  18.             //此行代码会阻塞,将一直等待别人的连接  
  19.             Socket s = ss.accept();  
  20.             socketList.add(s);  
  21.             //每当客户端连接后启动一条ServerThread线程为该客户端服务  
  22.             new Thread(new ServerThread(s)).start();  
  23.         }  
  24.    

 

ServerThrad.java

  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.io.OutputStream;  
  5. import java.net.Socket;  
  6.   
  7.   
  8.   
  9. //负责处理每个线程通信的线程类  
  10. public class ServerThread implements Runnable   
  11. {  
  12.     //定义当前线程所处理的Socket  
  13.     Socket s = null;  
  14.     //该线程所处理的Socket所对应的输入流  
  15.     BufferedReader br = null;  
  16.     public ServerThread(Socket s)  
  17.         throws IOException  
  18.     {  
  19.         this.s = s;  
  20.         //初始化该Socket对应的输入流  
  21.         br = new BufferedReader(new InputStreamReader(  
  22.             s.getInputStream() , "utf-8"));   //②  
  23.     }  
  24.     public void run()  
  25.     {  
  26.         try  
  27.         {  
  28.             String content = null;  
  29.             //采用循环不断从Socket中读取客户端发送过来的数据  
  30.             while ((content = readFromClient()) != null)  
  31.             {  
  32.                 //遍历socketList中的每个Socket,  
  33.                 //将读到的内容向每个Socket发送一次  
  34.                 for (Socket s : MyServer.socketList)  
  35.                 {  
  36.                     OutputStream os = s.getOutputStream();  
  37.                     os.write((content + "\n").getBytes("utf-8"));  
  38.                 }  
  39.             }  
  40.         }  
  41.         catch (IOException e)  
  42.         {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46.     //定义读取客户端数据的方法  
  47.     private String readFromClient()  
  48.     {  
  49.         try  
  50.         {  
  51.             return br.readLine();     
  52.         }  
  53.         //如果捕捉到异常,表明该Socket对应的客户端已经关闭  
  54.         catch (IOException e)  
  55.         {  
  56.             //删除该Socket。  
  57.             MyServer.socketList.remove(s);    //①  
  58.         }  
  59.         return null;  
  60.     }  
  61. }  


 

客户端代码:

布局文件:main.xml

  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. <LinearLayout   
  8.     android:orientation="horizontal"  
  9.     android:layout_width="fill_parent"  
  10.     android:layout_height="wrap_content"  
  11.     >  
  12. <!-- 定义一个文本框,它用于接受用户的输入 -->  
  13. <EditText  
  14.     android:id="@+id/input"    
  15.     android:layout_width="240px"   
  16.     android:layout_height="wrap_content"   
  17.     />  
  18. <Button  
  19.     android:id="@+id/send"    
  20.     android:layout_width="fill_parent"   
  21.     android:layout_height="wrap_content"   
  22.     android:paddingLeft="8px"  
  23.     android:text="@string/send"  
  24.     />  
  25. </LinearLayout>  
  26. <!-- 定义一个文本框,它用于显示来自服务器的信息 -->  
  27. <EditText  
  28.     android:id="@+id/show"   
  29.     android:layout_width="fill_parent"   
  30.     android:layout_height="fill_parent"   
  31.     android:gravity="top"  
  32.     android:editable="false"   
  33.     android:cursorVisible="false"   
  34.     />  
  35. </LinearLayout>  


Activity文件:MultiThreadClient.java

  1. package org.wwj.net;  
  2.   
  3. import java.io.OutputStream;  
  4. import java.net.Socket;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.EditText;  
  14.   
  15. public class MultiThreadClient extends Activity  
  16. {  
  17.     // 定义界面上的两个文本框  
  18.     EditText input, show;  
  19.     // 定义界面上的一个按钮  
  20.     Button send;  
  21.     OutputStream os;  
  22.     Handler handler;  
  23.   
  24.     @Override  
  25.     public void onCreate(Bundle savedInstanceState)  
  26.     {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.main);  
  29.         input = (EditText) findViewById(R.id.input);  
  30.         send = (Button) findViewById(R.id.send);  
  31.         show = (EditText) findViewById(R.id.show);  
  32.         Socket s;  
  33.         handler = new Handler()  
  34.         {  
  35.             @Override  
  36.             public void handleMessage(Message msg)  
  37.             {  
  38.                 // 如果消息来自于子线程  
  39.                 if (msg.what == 0x123)  
  40.                 {  
  41.                     // 将读取的内容追加显示在文本框中  
  42.                     show.append("\n" + msg.obj.toString());  
  43.                 }  
  44.             }  
  45.         };  
  46.         try  
  47.         {  
  48.             s = new Socket("183.30.181.228 ", 8000);  
  49.             // 客户端启动ClientThread线程不断读取来自服务器的数据  
  50.             new Thread(new ClientThread(s, handler)).start(); // ①  
  51.             os = s.getOutputStream();  
  52.         }  
  53.         catch (Exception e)  
  54.         {  
  55.             e.printStackTrace();  
  56.         }  
  57.         send.setOnClickListener(new OnClickListener()  
  58.         {  
  59.             @Override  
  60.             public void onClick(View v)  
  61.             {  
  62.                 try  
  63.                 {  
  64.                     // 将用户在文本框内输入的内容写入网络  
  65.                     os.write((input.getText().toString() + "\r\n")  
  66.                         .getBytes("utf-8"));  
  67.                     // 清空input文本框  
  68.                     input.setText("");  
  69.                 }  
  70.                 catch (Exception e)  
  71.                 {  
  72.                     e.printStackTrace();  
  73.                 }  
  74.             }  
  75.         });  
  76.     }  
  77. }  


子线程类:ClientThread.java

  1. package org.wwj.net;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.net.Socket;  
  7.   
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10.   
  11. public class ClientThread implements Runnable  
  12. {  
  13.     //该线程负责处理的Socket  
  14.     private Socket s;  
  15.     private Handler handler;  
  16.     //该线程所处理的Socket所对应的输入流  
  17.     BufferedReader br = null;  
  18.     public ClientThread(Socket s , Handler handler)  
  19.         throws IOException  
  20.     {  
  21.         this.s = s;  
  22.         this.handler = handler;  
  23.         br = new BufferedReader(  
  24.             new InputStreamReader(s.getInputStream()));  
  25.     }  
  26.     public void run()  
  27.     {  
  28.         try  
  29.         {  
  30.             String content = null;  
  31.             //不断读取Socket输入流中的内容。  
  32.             while ((content = br.readLine()) != null)  
  33.             {  
  34.                 // 每当读到来自服务器的数据之后,发送消息通知程序界面显示该数据  
  35.                 Message msg = new Message();  
  36.                 msg.what = 0x123;  
  37.                 msg.obj = content;  
  38.                 handler.sendMessage(msg);  
  39.             }  
  40.         }  
  41.         catch (Exception e)  
  42.         {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46. }  
posted on 2015-06-17 00:59  youzhu  阅读(139)  评论(0)    收藏  举报