Android学习笔记(31) --- 网络通信之Socket简易聊天室

在上一篇博文中,简单介绍了Socket的简单通信,这篇博文中将针对它进行简单的运用。接下来的例子是参考《Android应用开发揭秘》,不过上面有些小问题,例如字符编码问题。下面直接看下实现过程。

1、服务器:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
	private static int PORT = 54327;
	private static List<Socket> mSocketList = new ArrayList<Socket>();
	private ExecutorService mExcutorService;
	private ServerSocket mServerSocket;

	public static void main(String[] args) {
		new Server();
	}

	public Server() {
		try {
			mServerSocket = new ServerSocket(PORT);
			mExcutorService = Executors.newCachedThreadPool();
			Socket client = null;
			while (true) {
				client = mServerSocket.accept();
				mSocketList.add(client);
				mExcutorService.execute(new ThreadServer(client));
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	static class ThreadServer implements Runnable {

		private Socket mSocket;
		private BufferedReader mBufferedReader;
		private PrintWriter mPrintWriter;
		private String MSG = "";

		public ThreadServer(Socket socket) throws IOException {
			this.mSocket = socket;
			mBufferedReader = new BufferedReader(new InputStreamReader(
					mSocket.getInputStream(),"UTF-8"));
			mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
			MSG = mBufferedReader.readLine();
			System.out.println(MSG);
			sendMessage();
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				while ((MSG = mBufferedReader.readLine()) != null) {
						if(MSG.trim().equals("莫:exit")){
							MSG="下線了ing...";
							System.out.println("read-->" + MSG);
							sendMessage();
							mSocketList.remove(mSocket);
							mBufferedReader.close();
							mPrintWriter.close();
							mSocket.close();							
							break;
						}
						System.out.println("read-->" + MSG);
						sendMessage();
				}
			} catch (Exception e) {
				// TODO: handle exception
				System.out.println(e.getMessage());
			}
		}

		private void sendMessage() throws IOException {
			for (Socket client : mSocketList) {
				mPrintWriter = new PrintWriter(client.getOutputStream(), true);
				mPrintWriter.println(MSG);
			}
		}
	}
}

2、客户端:

package com.ideal.socket;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Net_SocketClientActivity extends Activity {
	private EditText mUser = null;//输入
	private Button mLogin = null;
	private EditText mSendMsg = null;//输入
	private Button mSend = null;
	private TextView mTextView = null;//记录
	private Socket mSocket;
	private Thread mThread;
	private BufferedReader mBufferedReader;
	private PrintWriter mPrintWriter;
	private String name = "";
	private String MSG="";

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mUser = (EditText) findViewById(R.id.user);
		mLogin = (Button) findViewById(R.id.login);
		mSendMsg = (EditText)findViewById(R.id.sendMsg);
		mSend = (Button)findViewById(R.id.sentBtn);
		mTextView = (TextView)findViewById(R.id.allMassage);
		 
		
		mLogin.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				try {
					mLogin.setVisibility(View.GONE);
					mUser.setVisibility(View.GONE);
					mSocket = new Socket("172.31.100.50",54327);
					//转码
					mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream(),"GBK"));
					mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
					name = mUser.getText().toString();
					try {						
						mPrintWriter.println(name+":login...");
						mPrintWriter.flush();
					} catch (Exception e) {
						// TODO: handle exception
						System.out.println(e.getMessage());
					}
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		});
 
		mSend.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
 
				try {
					String sendMsg = mSendMsg.getText().toString();
					mPrintWriter.println(name+":"+sendMsg);
					mPrintWriter.flush();
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
			}
		});
		mThread = new Thread(mRunnable);
		mThread.start();
		
	}
	private Runnable mRunnable =new Runnable() {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while(true){
				try {
					MSG=mBufferedReader.readLine();
					if(MSG!=null){
						mHandler.sendMessage(mHandler.obtainMessage());
					}else {
						break;
					}
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
	};
	Handler mHandler = new Handler(){
		public void handleMessage(Message msg){
			super.handleMessage(msg);
			try {
				mTextView.append("\n"+MSG);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	};
}

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/user"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button 
        android:id="@+id/login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"/>
    
    <EditText
        android:id="@+id/sendMsg"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/sentBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送" />
   
    <TextView
        android:id="@+id/allMassage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

看下效果图:

登陆...

登陆成功,等待发送信息...

发送信息


注:上面只是使用了模拟器作为客户端和PC作为服务端通信,当然,可以在多打开几个模拟器,这相当几个客户同时在聊天。如果你是在同一个实验室里面进行通行,那么在另一台电脑上使用的模拟器同样也能和其他台电脑上的模拟器通信。

存在问题:

1、刚开始时在模拟器和PC上都不能正常显示字符串,后来得知得转码。从上面的代码可看出:

在服务端:

mBufferedReader = new BufferedReader(new InputStreamReader(
					mSocket.getInputStream(),"UTF-8"));

在客户端:

	mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream(),"GBK"));

2、模拟器上完全实现和PC正常通信,但是如果使用真机作为客户端,则通信不了。目前知道原因是,通过SOCKET通信要在同一网段才能实现的。由于条件问题,所以这个改天再调试看看。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值