【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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。