android实现Socket通信二
2015-08-18 14:26
423 查看
在android实现Socket通信一中有个问题没有解决
br.readline()方法始终获得不到数据,为了能让它获得到数据,每次writer.write()后都要关闭socket。
发原因是客户单在writer.write()时由于没有写满缓冲区,也没有结束标识(“\n,\r,\r\n”)。
readLine():这是一个阻塞函数,如果没有读到东西是就一直堵着,不会有任何的返回值, 只有在数据流发生异常或者另一端被close()掉时,才会返回null值。 如果不指定buffer大小,则readLine()使用的buffer有8192个字符,在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回。
下面对一中的实现做一下小的修改,客户端向服务端写完数据后不在关闭输入输出流和socket。
NewSocketServer
MainClientActivity
br.readline()方法始终获得不到数据,为了能让它获得到数据,每次writer.write()后都要关闭socket。
发原因是客户单在writer.write()时由于没有写满缓冲区,也没有结束标识(“\n,\r,\r\n”)。
readLine():这是一个阻塞函数,如果没有读到东西是就一直堵着,不会有任何的返回值, 只有在数据流发生异常或者另一端被close()掉时,才会返回null值。 如果不指定buffer大小,则readLine()使用的buffer有8192个字符,在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回。
下面对一中的实现做一下小的修改,客户端向服务端写完数据后不在关闭输入输出流和socket。
NewSocketServer
package com.example.socket_server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.ServerSocket; import java.net.Socket; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.util.Log; import android.widget.Toast; public class NewSocketServer extends Service { public final static int M 4000 SG_RECEIVED = 1001; private final static String TAG = "SOCKET_SERVER"; /** * 显示客户单输入的信息 */ public Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_RECEIVED: Toast.makeText(NewSocketServer.this, "From Server : " + (String) msg.obj, Toast.LENGTH_SHORT).show(); break; } } }; @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { super.onCreate(); final int port = 8081; new Thread() { public void run() { ServerSocket server = null; try { server = new ServerSocket(port); while (true) { // server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 Socket socket = server.accept(); // accept一个socket,和客户单建立连接 // 每接收到一个Socket就建立一个新的线程来处理它 new Thread(new RecevierRunnable(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } /** * 独立的线程来接收消息 */ class RecevierRunnable implements Runnable { Socket socket; String ip; public RecevierRunnable(Socket socket) { this.socket = socket; this.ip = socket.getInetAddress().getHostAddress(); } public void run() { try { receivedMsgBySocket(); } catch (Exception e) { e.printStackTrace(); } } private void receivedMsgBySocket() throws Exception { Log.d(TAG, "receivedMsgBySocket() start"); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); Writer writer = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); String strFromClient = br.readLine(); while(strFromClient != null && !strFromClient.equals("bye")){ Message msg = handler.obtainMessage(MSG_RECEIVED); msg.obj = strFromClient; handler.sendMessage(msg); writer.write("你好,客户端:" + ip + ",我是服务端,我已经收到你的消息了,你说 :" + msg + "\r\n"); writer.flush();// 调用flush()方法只是将数据写入操作系统缓存中,并不保证数据会立即发送 strFromClient = br.readLine(); } writer.write("你好,客户端,再见~~~~" + "\r\n"); writer.flush(); br.close(); writer.close(); socket.close(); Log.d(TAG, "receivedMsgBySocket() end"); } } }
MainClientActivity
package com.example.socket_client; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; 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.Toast; public class MainClientActivity extends Activity implements OnClickListener { private final static String TAG = "SOCKET_CLIENT"; public final static int MSG_FROM_SERVER = 1002; EditText input = null; Button btnSend = null; ServerSocket serverSocket = null; private Socket mSocket; private BufferedWriter bfWriter; private BufferedReader bfReader; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { if(msg.what == MSG_FROM_SERVER){ input.setText(null); Toast.makeText(MainClientActivity.this, "收到了服务器消息 :" + (String)msg.obj, Toast.LENGTH_LONG).show(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); input = (EditText)findViewById(R.id.id_input); btnSend = (Button)findViewById(R.id.btnSend); btnSend.setOnClickListener(this); new Thread(){ public void run(){ init(); new Thread(new ReceiverRunnable()).start(); } }.start(); } private void init(){ try { mSocket = new Socket("127.0.0.1",8081);// 连接服务器端 bfWriter = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())); // 由Socket对象得到输入流,并构造相应的BufferedReader对象 读取服务器端发回来的消息 bfReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream())); } catch (IOException e) { Log.d(TAG, "init() IOException = " + e); } } @Override public void onClick(View arg0) { new Thread(){ public void run(){ try{ String inputStr = input.getText().toString() + "\r\n"; Log.d(TAG, "inputStr = " + inputStr); if(inputStr != null){ bfWriter.write(inputStr); bfWriter.flush(); } }catch(Exception e) { Log.d(TAG, "", e); } } }.start(); } /** * 接收服务器端返回来的消息 * */ class ReceiverRunnable implements Runnable { @Override public void run() { String msgFromServer = null; try { if(bfReader != null){ msgFromServer = bfReader.readLine(); } Log.d(TAG, "ReceiverRunnable , msgFromServer = " + msgFromServer); while (msgFromServer != null && !msgFromServer.equals("bye")) { sendMsgToHandler(msgFromServer); if(bfReader != null){ msgFromServer = bfReader.readLine(); } } sendMsgToHandler(msgFromServer + ", 再见!"); bfReader.close(); bfWriter.close(); mSocket.close(); } catch (IOException e) { Log.d(TAG, "ReceiverRunnable IOException", e); } } } public void sendMsgToHandler(String strMsg){ Message msg = mHandler.obtainMessage(MSG_FROM_SERVER); msg.obj = strMsg; mHandler.sendMessage(msg); } @Override protected void onDestroy() { super.onDestroy(); try { bfWriter.close(); bfReader.close(); mSocket.close(); } catch (IOException e) { Log.d(TAG, "onDestroy IOException", e); } } }
相关文章推荐
- Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
- Android笔记:ListView
- android 通过eclipse混淆代码 打包 + proguard 总结
- 一个解决android多渠道打包的问题插件之(兰贝壳儿)
- Android四大组件之服务-Service 原理和应用开发详解
- 浅谈接口回调以及在Android中的使用
- android问题
- 从零开始--系统深入学习Android
- android 16进制/10进制/2进制转换
- Android Studio 快捷键 (Mac OS X 10.5+)
- Android开发设置软键盘收索键
- 《开源项目系列》 --- 简阅
- Android Studio NDK 学习之接受Java传入的字符串
- 基于android 图像基本处理项目demo源码释放(jarlen)
- Android Edittext 开发常见问题总结(焦点、输入、键盘弹出等)
- 开发Android硬件访问服务
- Android源码分析之Handler机制
- Activity 生命周期
- Android对话框的几种形式
- 关于AndroidStudio导入项目报错的问题