今天是入职第一天,老大知道我之前没有接触过socket,而公司用socket比较多,所以下午让我尝试写一下Android客户端和server基于TCP Socket通信
大概就是一个Android客户端,向服务器发送用户密码,服务端验证,返回json格式数据。
客户端:
- MainActivity代码:
package com.boke.socketclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
public EditText et_username, et_password;
public TextView tv_result;
public Button btn_login;
public Socket socket = null;
public String buffer = "";
public Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x11) {
Bundle bundle = msg.getData();
String result = bundle.getString("msg");
tv_result.setText(result);
JSONObject resultJson;
try {
resultJson = new JSONObject(result);
Toast.makeText(MainActivity.this,
resultJson.getString("msg"), Toast.LENGTH_SHORT)
.show();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* 初始化控件
*/
private void init() {
et_username = (EditText) findViewById(R.id.et_username);
et_password = (EditText) findViewById(R.id.et_password);
tv_result = (TextView) findViewById(R.id.tv_result);
btn_login = (Button) findViewById(R.id.btn_login);
// 设置监听事件
btn_login.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
login();
}
});
}
/**
* 登录
*/
private void login() {
String username = et_username.getText().toString();
String password = et_password.getText().toString();
JSONObject data = new JSONObject();
try {
data.put("username", username);
data.put("password", password);
} catch (JSONException e) {
e.printStackTrace();
}
new MyThread(data).start();
}
class MyThread extends Thread {
public JSONObject data;
public MyThread(JSONObject data) {
this.data = data;
}
@Override
public void run() {
// 定义消息
Message msg = new Message();
msg.what = 0x11;
Bundle bundle = new Bundle();
bundle.clear();
OutputStream ou = null;
InputStream in = null;
BufferedReader bff = null;
try {
// 连接服务器 并设置连接超时为5秒
socket = new Socket();
socket.connect(new InetSocketAddress("10.0.2.2", 30000), 5000);// 模拟器与本机通信地址
//如果是eclipse自带模拟器用这个地址,如果是genymotion的话使用10.0.3.2。
// 获取输入输出流
ou = socket.getOutputStream();
in = socket.getInputStream();
// 向服务器发送信息
Log.v("TAG", "TAG--向服务器发送的消息为:" + data.toString());
ou.write(data.toString().getBytes("gbk"));
ou.flush();
socket.shutdownOutput();
bff = new BufferedReader(new InputStreamReader(in));
// 读取发来服务器信息
String line = "";
buffer = "";
while ((line = bff.readLine()) != null) {
buffer = line + buffer;
}
Log.v("TAG", "TAG--服务器的返回为:" + buffer);
bundle.putString("msg", buffer.toString());
msg.setData(bundle);
// 发送消息 修改UI线程中的组件
myHandler.sendMessage(msg);
} catch (SocketTimeoutException aa) {
// 连接超时 在UI界面显示消息
bundle.putString("msg", "服务器连接失败!请检查网络是否打开");
msg.setData(bundle);
// 发送消息 修改UI线程中的组件
myHandler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭输入输出流
try {
// 关闭各种输入输出流
bff.close();
ou.close();
in.close();
socket.close();// socket最后关闭
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
- activity_main.xml布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="${relativePackage}.${activityClass}" >
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="16dp"
android:hint="请输入用户名" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="16dp"
android:hint="请输入密码"
android:inputType="textPassword" />
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="16dp"
android:text="登录" />
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/hello_world" />
</LinearLayout>
- AndroidManifest.xml中记得添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
服务端:
- SoketServer.java代码:
package com.boke.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SoketServer {
/**
* 程序入口
*
* @param args
*/
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(30000);
System.out.println("等待客户端连入...");
while(true){
//等待客户端连入
Socket socket = serverSocket.accept();
new Thread(new AndroidRunnable(socket)).start();
}
}
}
- AndroidRunnable.java代码:
package com.boke.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import net.sf.json.JSONObject;
public class AndroidRunnable implements Runnable {
public Socket socket = null;
public AndroidRunnable(Socket socket) {
this.socket = socket;
}
public void run() {
System.out.println("客户端连入成功...");
String line = "";
InputStream input = null;
OutputStream output = null;
BufferedReader bff = null;
JSONObject result = new JSONObject();// 需要导入json的多个jar包,http://download.csdn.net/detail/u011381488/6457097
try {
// 向客户端发送信息
output = socket.getOutputStream();
input = socket.getInputStream();
bff = new BufferedReader(new InputStreamReader(input));
// 获取客户端的信息
while ((line = bff.readLine()) != null) {
System.out.println("接收到客户端的消息为:" + line);
socket.shutdownInput();// 半闭socket
// 向客户端发送消息
JSONObject jsonObject = JSONObject.fromObject(line);
String username = jsonObject.getString("username");
String password = jsonObject.getString("password");
// 验证用户名、密码
if (username.equals("123") && password.equals("456")) {
result.put("state", "0");
result.put("msg", "登录成功");
} else {
result.put("state", "1");
result.put("msg", "密码错误");
}
System.out.println("向客户端发送的消息为:" + result.toString());
OutputStream out = socket.getOutputStream();
out.write(result.toString().getBytes());
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭输入输出流
try {
output.close();
bff.close();
input.close();
socket.close();// socket最后关闭
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行效果:
- 学习才刚开始,希望能坚持,多理解,加油!