一、概述
下面的实现中为了讲解的方便,并没有采用多线程的方法,因此通信过程中会阻塞UI线程,而且只涉及了单向通信(客户端-->服务器),完善的程序(多线程,双向通信)会在提高篇再讲解。
二、要求
熟悉socket编程。
三、实现
新建工程MyClient,修改/res/layout/main.xml文件,在里面添加一个EditText和两个Button,完整的main.xml文件如下:
[代码]xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="请输入要发送的内容"
/>
<Button
android:id="@+id/connectbutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="连接"
/>
<Button
android:id="@+id/sendbutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="发送"
/>
</LinearLayout>
接着,修改MyClientActivity.java文件,定义一个socket对象和一个OutputStream对象(用于发送数据),完整的内容如下:
[代码]java代码:
package com.nan.client;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MyClientActivity extends Activity
{
private EditText mEditText = null;
private Button connectButton = null;
private Button sendButton = null;
private Socket clientSocket = null;
private OutputStream outStream = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mEditText = (EditText)this.findViewById(R.id.edittext);
connectButton = (Button)this.findViewById(R.id.connectbutton);
sendButton = (Button)this.findViewById(R.id.sendbutton);
sendButton.setEnabled(false);
//连接按钮监听
connectButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
try
{
//实例化对象并连接到服务器
clientSocket = new Socket("183.41.101.71",8888);
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
displayToast("连接成功!");
connectButton.setEnabled(false);
sendButton.setEnabled(true);
}
});
//发送数据按钮监听
sendButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
byte[] msgBuffer = null;
//获得EditTex的内容
String text = mEditText.getText().toString();
try {
//字符编码转换
msgBuffer = text.getBytes("GB2312");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
//获得Socket的输出流
outStream = clientSocket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//发送数据
outStream.write(msgBuffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
displayToast("发送成功!");
}
});
}
//显示Toast函数
private void displayToast(String s)
{
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
}
}
接着,新建工程MyServer,同样修改/res/layout/main.xml文件,如下:
[代码]xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15dip"
/>
</LinearLayout>
修改MyServerActivity.java文件,比较简单,代码中有详细注释,如下:
[代码]java代码:
package com.nan.server;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MyServerActivity extends Activity
{
private TextView mTextView = null;
private InputStream mInputStream = null;
private Socket clientSocket = null;
private ServerSocket mServerSocket = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView)this.findViewById(R.id.textview);
try {
//实例化ServerSocket对象并设置端口号为8888
mServerSocket = new ServerSocket(8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//等待客户端的连接(阻塞)
clientSocket = mServerSocket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//获得socket的输入流
mInputStream = clientSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buf = new byte[512];
String str = null;
try {
//读取输入的数据(阻塞读)
mInputStream.read(buf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//字符编码转换
str = new String(buf, "GB2312").trim();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//显示接收到的数据
mTextView.setText("收到的数据:"+str);
}
}
最后在两个工程的AndroidMainfest.xml文件中都加入权限:
1 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
到这里,客户端和服务器的程序都写好了,在模拟器上运行客户端程序:
在真机上运行服务器程序:
接着,点击客户端“连接”按钮,输入一些内容再点击“发送”按钮:
此时服务器端的情况如下:
可见成功接收了客户端发送过来的数据。