今天开始做的,由于是根据以前的一个小项目改的,不是从头做的,所以没法把所有代码共享,就在这里记录一下每天的思路,希望能给需要的同学抛砖引玉。
思路其实就是上一篇博客的内容,完善了一下代码,实现了从android发送一句话给服务器,然后服务器把这句话再发回来。
能够实现这样的正常通信,后面的工作应该不会太难。下面开始贴些主要的代码。
首先是服务器端,用了两个类,一个MyServer,处理android发来的消息;一个ServerThread,MyServer每接受到一个用户请求,就开启一个ServerThread去处理。
MyServer:
package server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class MyServer { ServerSocket server = null; public MyServer() { this.startServer(); } void startServer() { int i = 0; try { server = new ServerSocket(8888, 3); System.out.println("==========start==========="); while (true) { Socket socket = server.accept(); i++; System.out.println("第" + i + "个用户连接成功!"); new Thread(new ServerThread(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } } }
端口号写死的为8888。
ServerThread:
package server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; public class ServerThread implements Runnable { private Socket socket; public ServerThread(Socket socket) { this.socket = socket; } // 任务是为一个用户提供服务 @Override public void run() { try { try { // 读取客户端传过来信息的DataInputStream DataInputStream in = new DataInputStream( socket.getInputStream()); // 向客户端发送信息的DataOutputStream DataOutputStream out = new DataOutputStream( socket.getOutputStream()); while (true) { // 读取来自客户端的信息 String accpet = in.readUTF(); System.out.println(accpet); out.writeUTF("服务器:" + accpet); } } finally {// 建立连接失败的话不会执行socket.close(); socket.close(); } } catch (IOException e) { e.printStackTrace(); } } }
线程开始后一直接受客户端发来的消息,然后返回给客户端。
以上是服务器端的内容,能够同时处理多个用户的请求。
下面是android客户端的代码。
MainActivity:
package jason.smartdinner; import serverhelper.ClientHelper; 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; public class MainActivity extends Activity { public static final String TAG = "MAINACTIVITY"; void log(String msg) { Log.d(TAG, msg); } TextView output; EditText input; Button send; ClientHelper clientHelper; Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: Bundle b = msg.getData(); String msg2 = b.getString("update"); log(msg2); output.setText(msg2); break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread() { public void run() { clientHelper = new ClientHelper(); } }.start(); output = (TextView) findViewById(R.id.output); input = (EditText) findViewById(R.id.input); send = (Button) findViewById(R.id.send); send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread() { @Override public void run() { // TODO Auto-generated method stub super.run(); String message = input.getText().toString(); clientHelper.send(message); String receive = clientHelper.read(); log(receive); Message update = new Message(); update.what = 1; Bundle bundle = new Bundle(); bundle.putString("update", receive); update.setData(bundle); handler.sendMessage(update); } }.start(); } }); } }
大家会注意到里面我用了好几个线程,这里需要注意的是,android的网络连接请求不能再主线程里,否则会报错android.os.NetworkOnMainThreadException
所以每个涉及网络连接的都新开了线程去处理。其他就简单了,处理下界面更新。
ClientHelper:
package serverhelper; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import android.util.Log; public class ClientHelper { public static final String TAG = "CLIENTHELPER"; void log(String msg){ Log.d(TAG, msg); } DataInputStream in; DataOutputStream out; Socket socket = null; public ClientHelper() { try { socket = new Socket("192.168.1.100", 8888); in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void send(String msg) { try { out.writeUTF(msg); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String read() { String accept = "未接收到信息"; try { accept = in.readUTF(); log(accept); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return accept; } }
这个就是负责与服务器交互的类,发送和接受数据两个方法。其中socket的ip地址是我电脑的本地ip,上篇博客里有提到。
代码就先不上传了,基本上设计到的都在上面贴出来了,细心看看就明白了,完全可以自己搞出来。
作者:jason0539
微博:http://weibo.com/2553717707
博客:http://blog.csdn.net/jason0539(转载请说明出处)