链接地址: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 <Button15 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 block104 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 @Override24 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对象并设置端口号为888833 mServerSocket = new ServerSocket(8888);34 } catch (IOException e) {35 // TODO Auto-generated catch block36 e.printStackTrace();37 }38 39 try {40 //等待客户端的连接(阻塞)41 clientSocket = mServerSocket.accept();42 } catch (IOException e) {43 // TODO Auto-generated catch block44 e.printStackTrace();45 }46 47 try {48 //获得socket的输入流49 mInputStream = clientSocket.getInputStream();50 } catch (IOException e) {51 // TODO Auto-generated catch block52 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 block63 e.printStackTrace();64 }65 66 try {67 //字符编码转换68 str = new String(buf, "GB2312").trim();69 } catch (UnsupportedEncodingException e) {70 // TODO Auto-generated catch block71 e.printStackTrace();72 }73 //显示接收到的数据74 mTextView.setText("收到的数据:"+str);75 76 }77 78 }
最后在两个工程的AndroidMainfest.xml文件中都加入权限:
1 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
到这里,客户端和服务器的程序都写好了,在模拟器上运行客户端程序:
在真机上运行服务器程序:
接着,点击客户端“连接”按钮,输入一些内容再点击“发送”按钮:
此时服务器端的情况如下:
可见成功接收了客户端发送过来的数据。