您的位置:首页 > 移动开发 > Android开发

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

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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: