链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html

一、概述

网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络编程是非常有必要的,而我觉得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>

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

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

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

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

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

Android应用开发基础篇(12)-----Socket通信的更多相关文章

  1. Android应用开发基础篇(1)-----Button

    Android应用开发基础篇(1)-----Button   一.概述        Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用      新建一个工程, ...

  2. Android应用开发基础篇(3)-----ListView

    一.概述 ListView是一个列表显示控件,它的应用非常广泛,在很多应用程序中都可以看到它的身影,比如来电通,网易新闻等等,特别是QQ.因此非常有必要熟练掌握它. 二.要求 能够利用ListView ...

  3. Android应用开发基础篇(4)-----TabHost(选项卡)

    一.概述 TabHost是一种用来显示标签的组件,不清楚?看一下来电通这个应用就知道了.这个组件用起来与其他组件不太一样,它需要继承TabActivity这个类,还有它的布局文件与我们平时用的也有些不 ...

  4. Android应用开发基础篇(14)-----自定义标题栏

    一.概述 每一个应用程序默认的标题栏(注意与状态栏的区别)只有一行文字(新建工程时的名字),而且颜色.大小等都是固定的,给人的感觉比较单调.但当程序需要美化的时候,那么修改标题栏是就是其中一项内容,虽 ...

  5. Android应用开发基础篇(13)-----GestureDetector(手势识别)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/05/2381025.html 一.概述 GestureDetector是一个用于识别手势的类,这 ...

  6. Android应用开发基础篇(9)-----SharedPreferences

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/27/2370319.html 一.概述 对于SharedPreferences,我吧它理解为一种 ...

  7. Android应用开发基础篇(12)-----Socket通信(转载)

    转自:http://www.devdiv.com/android_socket_-blog-258060-10594.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络 ...

  8. Android应用开发基础篇(6)-----Service

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/20/2360336.html 一.概述 我们知道,Service是Android的四大组件之一. ...

  9. Android应用开发基础篇(2)-----Notification(状态栏通知)

    一.概述      Notification这个部件的功能是在状态栏里显示消息提醒,比如有未读的短信或者是未接的电话,那么状态栏里都会有显示,更或者是从某个应用(比如QQ,酷我音乐等等)里按Home键 ...

随机推荐

  1. cell与cell之间的间距问题,以及section跟随屏幕滑动而滑动问题

    苹果在cell与cell之间默认没有间距,这样有时候不能满足我们界面要求,所以我们就需要将cell设置为分组模式(也就是每组一行或者多行,分为n组),然后我们就可以在代理中根据自己的需求设计cell之 ...

  2. 浅谈JavaScript中的正则表达式

    引言 对于正则表达式我想作为程序员肯定使用过它,那天书般的表达方式,我用一次就记住它了.这篇博客先介绍一些正则表达式的内容,然后介绍JavaScript中对正则表达式特有的改进.下面开始介绍正则表达式 ...

  3. https和http

    今天登网站的时候用https登的,没登上去用http找到网站了,于是就去百度了下他俩的区别简单的画了俩图.

  4. rm删除命令

    linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有 ...

  5. textContent、innerText的用法,在文档中插入纯文本

    有时候需要查询纯文本形式的元素内容,或者在文档中插入纯文本.标准的方法是用Node的textContent属性来实现: var para = document.getElementsByTagName ...

  6. 【 D3.js 高级系列 】 总结

    高级系列的教程已经完结,特此总结. 月初的时候曾说过本月内完结高级教程,今天是最后一天,算是可以交差了.O(∩_∩)O~ 如此一来,[入门]-[进阶]-[高级]三个系列的教程算是完成了.本教程的目的在 ...

  7. 一步一步学习SignalR进行实时通信_6_案例

    原文:一步一步学习SignalR进行实时通信_6_案例 一步一步学习SignalR进行实时通信\_6_案例1 一步一步学习SignalR进行实时通信_6_案例1 前言 类的定义 各块功能 后台 上线 ...

  8. [6] 算法路 - 双向冒泡排序的Shaker

    Shaker序列 –算法 1. 气泡排序的双向进行,先让气泡排序由左向右进行.再来让气泡排序由右往左进行,如此完毕一次排序的动作 2. 使用left与right两个旗标来记录左右两端已排序的元素位置. ...

  9. PHP的ntohl网络字节序函数及相关知识

    PHP与C服务器的socket通信,在做数据转换的时候,PHP没有提供对应将网络字节序和机器字节序相互转换的程序,但是根据函数的意义,我们可以做相应的转换来实现这一函数: function ntohl ...

  10. codeforces1093G Multidimensional Queries 【线段树】

    题目分析: 搜索2^k种情况,线段树分别处理就行了,正确性明显. 代码: #include<bits/stdc++.h> using namespace std; ; int n,k; ] ...