zoukankan      html  css  js  c++  java
  • 【Android學習專題】網絡通信篇:Socket TCP(简易聊天室)


    【Android學習專題】網絡通信篇:Socket TCP(简易聊天室)

       SkySeraph Feb 12nd 2012  SZ

    Email:skyseraph00@163.com 


    简易界面

    Android客户端登录

    Android客户端登录后服务器和PC客户端界面

    Android客户端和PC客户端聊天

     

    注:在同一台PC机下测试,故所有的IP都一样了。

     


    相关原理

    1 Socket传输模式

    2 Socket构造

    3 ServiceSocket构造

    4 客户端Socket

    5 输入输出流

    6 关闭Socket和流


    完整源码

    1 服务器

     1 public class tcpservice
    2 {
    3 // ////////////////////////////////////////////////////////////////////////////////////
    4 //服务器端口
    5 private static final int SERVERPORT = 8888;
    6 //存储所有客户端Socket连接对象
    7 private static List<Socket> mClientList = new ArrayList<Socket>();
    8 //线程池
    9 private ExecutorService mExecutorService;
    10 //ServerSocket对象
    11 private ServerSocket mServerSocket;
    12 //开启服务器
    13 public static void main(String[] args)
    14 {
    15 new tcpservice();
    16 }
    17 //
    18 public tcpservice()
    19 {
    20 try
    21 {
    22 //设置服务器端口
    23 mServerSocket = new ServerSocket(SERVERPORT);
    24 //创建一个线程池
    25 mExecutorService = Executors.newCachedThreadPool();
    26 System.out.println("start...");
    27 //用来临时保存客户端连接的Socket对象
    28 Socket client = null;
    29 while (true)
    30 {
    31 //接收客户连接并添加到list中
    32 client = mServerSocket.accept();
    33 mClientList.add(client);
    34 //开启一个客户端线程
    35 mExecutorService.execute(new ThreadServer(client));
    36 }
    37 }
    38 catch (IOException e)
    39 {
    40 e.printStackTrace();
    41 }
    42 }
    43 //每个客户端单独开启一个线程
    44 static class ThreadServer implements Runnable
    45 {
    46 private Socket mSocket;
    47 private BufferedReader mBufferedReader;
    48 private PrintWriter mPrintWriter;
    49 private String mStrMSG;
    50
    51 public ThreadServer(Socket socket) throws IOException
    52 {
    53 this.mSocket = socket;
    54 mBufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    55 mStrMSG = "user:"+this.mSocket.getInetAddress()+" come total:" + mClientList.size();
    56 sendMessage();
    57 }
    58 public void run()
    59 {
    60 try
    61 {
    62 while ((mStrMSG = mBufferedReader.readLine()) != null)
    63 {
    64 if (mStrMSG.trim().equals("exit"))
    65 {
    66 //当一个客户端退出时
    67 mClientList.remove(mSocket);
    68 mBufferedReader.close();
    69 mPrintWriter.close();
    70 mStrMSG = "user:"+this.mSocket.getInetAddress()+" exit total:" + mClientList.size();
    71 mSocket.close();
    72 sendMessage();
    73 break;
    74 }
    75 else
    76 {
    77 mStrMSG = mSocket.getInetAddress() + ":" + mStrMSG;
    78 sendMessage();
    79 }
    80 }
    81 }
    82 catch (IOException e)
    83 {
    84 e.printStackTrace();
    85 }
    86 }
    87 //发送消息给所有客户端
    88 private void sendMessage() throws IOException
    89 {
    90 System.out.println(mStrMSG);
    91 for (Socket client : mClientList)
    92 {
    93 mPrintWriter = new PrintWriter(client.getOutputStream(), true);
    94 mPrintWriter.println(mStrMSG);
    95 }
    96 }
    97 }
    98 }

     

    2 Android客户端java

      1 public class tcpclient extends Activity
    2 {
    3 // 声明对象
    4 private Button mInButton, mSendButton;
    5 private EditText mEditText01, mEditText02;
    6 private static final String SERVERIP = "10.120.220.6";
    7 private static final int SERVERPORT = 8888;
    8 private Thread mThread = null;
    9 private Socket mSocket = null;
    10 private BufferedReader mBufferedReader = null;
    11 private PrintWriter mPrintWriter = null;
    12 private String mStrMSG = "";
    13 private static String TAG = camera.class.getSimpleName();
    14 // ////////////////////////////////////////////////////////////////////////////////////
    15 @Override
    16 protected void onCreate(Bundle savedInstanceState)
    17 {
    18 // TODO Auto-generated method stub
    19 super.onCreate(savedInstanceState);
    20 setContentView(R.layout.myinternet_tcpclient);
    21
    22 mInButton = (Button) findViewById(R.id.myinternet_tcpclient_BtnIn);
    23 mSendButton = (Button) findViewById(R.id.myinternet_tcpclient_BtnSend);
    24 mEditText01 = (EditText) findViewById(R.id.myinternet_tcpclient_EditText01);
    25 mEditText02 = (EditText) findViewById(R.id.myinternet_tcpclient_EditText02);
    26 // ////////////////////////////////////////////////////////////////////////////////////
    27 // 登陆
    28 mInButton.setOnClickListener(new OnClickListener()
    29 {
    30 public void onClick(View v)
    31 {
    32 try
    33 {
    34 // ①Socket实例化,连接服务器
    35 mSocket = new Socket(SERVERIP, SERVERPORT);
    36 // ②获取Socket输入输出流进行读写操作
    37 mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
    38 mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
    39 } catch (Exception e)
    40 {
    41 // TODO: handle exception
    42 Log.e(TAG, e.toString());
    43 }
    44 }
    45 });
    46 // ////////////////////////////////////////////////////////////////////////////////////
    47 // 发送消息
    48 mSendButton.setOnClickListener(new OnClickListener()
    49 {
    50 public void onClick(View v)
    51 {
    52 try
    53 {
    54 // 取得编辑框中我们输入的内容
    55 String str = mEditText02.getText().toString() + "\n";
    56 // 发送给服务器
    57 mPrintWriter.print(str);
    58 mPrintWriter.flush();
    59 } catch (Exception e)
    60 {
    61 // TODO: handle exception
    62 Log.e(TAG, e.toString());
    63 }
    64 }
    65 });
    66 mThread = new Thread(mRunnable);
    67 mThread.start();
    68 }
    69 // ////////////////////////////////////////////////////////////////////////////////////
    70 // 线程:监听服务器发来的消息
    71 private Runnable mRunnable = new Runnable()
    72 {
    73 public void run()
    74 {
    75 while (true)
    76 {
    77 try
    78 {
    79 if ((mStrMSG = mBufferedReader.readLine()) != null)
    80 {
    81 mStrMSG += "\n";// 消息换行
    82 mHandler.sendMessage(mHandler.obtainMessage());// 发送消息
    83 }
    84 } catch (Exception e)
    85 {
    86 Log.e(TAG, e.toString());
    87 }
    88 }
    89 }
    90 };
    91 // ////////////////////////////////////////////////////////////////////////////////////
    92 Handler mHandler = new Handler()//更新界面的显示(不能直接在线程中更新视图,因为Android线程是安全的)
    93 {
    94 public void handleMessage(Message msg)
    95 {
    96 super.handleMessage(msg);
    97 // 刷新
    98 try
    99 {
    100 mEditText01.append(mStrMSG);// 将聊天记录添加进来
    101 } catch (Exception e)
    102 {
    103 Log.e(TAG, e.toString());
    104 }
    105 }
    106 };
    107 // ////////////////////////////////////////////////////////////////////////////////////
    108 }

    布局文件

    View Code
     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/myinternet_tcpclient_EditText01"
    9 android:layout_width="fill_parent"
    10 android:layout_height="200px"
    11 android:text="聊天记录:\n" >
    12 </EditText>
    13
    14 <EditText
    15 android:id="@+id/myinternet_tcpclient_EditText02"
    16 android:layout_width="fill_parent"
    17 android:layout_height="wrap_content"
    18 android:text="输入要发送的内容" >
    19 </EditText>
    20
    21 <LinearLayout
    22 android:layout_width="fill_parent"
    23 android:layout_height="wrap_content"
    24 android:orientation="horizontal"
    25 android:gravity="center" >
    26
    27 <Button
    28 android:id="@+id/myinternet_tcpclient_BtnIn"
    29 android:layout_width="200px"
    30 android:layout_height="wrap_content"
    31 android:text="登陆" />
    32
    33 <Button
    34 android:id="@+id/myinternet_tcpclient_BtnSend"
    35 android:layout_width="200px"
    36 android:layout_height="wrap_content"
    37 android:text="发送" />
    38 </LinearLayout>
    39
    40 </LinearLayout>

     

    3 PC客户端

     1 public class tcpclient2
    2 {
    3 private static final int PORT = 8888;
    4 private static ExecutorService exec = Executors.newCachedThreadPool();
    5
    6 public static void main(String[] args) throws Exception
    7 {
    8 new tcpclient2();
    9 }
    10
    11 public tcpclient2()
    12 {
    13 try
    14 {
    15 Socket socket = new Socket("10.120.220.6", PORT);
    16 exec.execute(new Sender(socket));
    17
    18 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    19 String msg;
    20 while ((msg = br.readLine()) != null)
    21 {
    22 System.out.println(msg);
    23 }
    24 } catch (Exception e)
    25 {
    26
    27 }
    28 }
    29
    30 // 客户端线程获取控制台输入消息
    31 static class Sender implements Runnable
    32 {
    33 private Socket socket;
    34
    35 public Sender(Socket socket)
    36 {
    37 this.socket = socket;
    38 }
    39
    40 public void run()
    41 {
    42 try
    43 {
    44 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    45 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
    46 String msg;
    47
    48 while (true)
    49 {
    50 msg = br.readLine();
    51 pw.println(msg);
    52
    53 if (msg.trim().equals("exit"))
    54 {
    55 pw.close();
    56 br.close();
    57 exec.shutdownNow();
    58 break;
    59 }
    60 }
    61 } catch (Exception e)
    62 {
    63 e.printStackTrace();
    64 }
    65 }
    66 }
    67 // ////////////////////////////////////////////////////////////////////////////////////
    68 }

    Refs:

    《Android应用开发揭秘》

     


    作者:skyseraph
    出处:http://www.cnblogs.com/skyseraph/
    更多精彩请直接访问SkySeraph个人站点:http://skyseraph.com//
    Email/GTalk: zgzhaobo@gmail.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Web 安全 —— XSS攻击的原理
    HTTP缓存
    JavaScript 事件循环机制(Event Loop)
    搭建前端监控系统
    电脑 直接下载cyida deb
    基于样例的传统图像修补算法实现
    Android WorkManager 定时任务
    Android WorkManager工作约束,延迟与查询工作
    微信小程序地图如何显示附近厕所WC步行路线
    物流解决方案再添利器 腾讯位置服务推出货运“三件套”
  • 原文地址:https://www.cnblogs.com/skyseraph/p/2391601.html
Copyright © 2011-2022 走看看