现在我们用一台电脑做服务器,一部手机做客户端,来实现手机与电脑之间的通信啦。首先,异曲同工,在手机上建立客户端与在电脑上是差不多的,首先我们现在电脑上面建立服务器如下:
- package 手机与PC端通信;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class Server {
- public void setup(int port){
- try {
- //创建服务器
- ServerSocket host=new ServerSocket(port);
- System.out.println("通信端口"+port+"成功开启");
- while(true){
- //等待客户端访问
- Socket socket=host.accept();
- System.out.println("有人访问了");
- //把跟客户端交流的事情交给线程处理
- ServerThread st = new ServerThread(socket);
- //开启线程
- st.start();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static void main(String[] args){
- //传入端口号
- new Server().setup(8888);
- }
- }
接下来建立线程来处理socket得到的输入流以及输出流:
- package 手机与PC端通信;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.Socket;
- public class ServerThread extends Thread {
- private Socket socket;
- private DataOutputStream dos;
- public ServerThread(Socket socket){
- this.socket=socket;
- }
- public void run(){
- //得到网络连接socket得到的输出输入流
- try {
- //输入流
- InputStream input=socket.getInputStream();
- DataInputStream dis=new DataInputStream(input);
- //得到客户端的输出流
- dos=new DataOutputStream(socket.getOutputStream());
- //读取客户端发到服务端的字节
- while(true){
- int msgType=dis.readInt();
- int len=dis.readInt();
- byte[] bytes=new byte[len];
- dis.readFully(bytes);
- String content=new String(bytes,"GB2312");
- System.out.println("客户端说:"+content);
- //这里是发到客户端的
- String replyString = "服务器收到了("+content+")";
- bytes = replyString.getBytes("GB2312");
- //写进是文字 1
- dos.writeInt(1);
- //输出流写进字节长度
- dos.writeInt(bytes.length);
- //写进字节
- dos.write(bytes);
- //刷新
- dos.flush();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
这些内容在上节中都已经讲过,这里不做过多阐述
接下来就是重点内容啦,就是在Android中建立客户端,这里我们要使用带安卓插件的eclipse来编写
首先处理界面,我大概定义了一个textview来显示聊天内容,editText来进行输入框的角色,再者就是一个发送按钮,这样一个简单的聊天界面就已经完成了,如下,简洁的小界面,读者们可以自行美化界面哈:
***记得绑定发送按钮到指定函数哦。#p#
接下来就是在MainActivity中开始动工了,动工之前,讲一个非常重要的函数Handler,我们知道,在UI界面主线程中,我们肯定要获取到输入框输入的文字来发送到服务器上,Android里面的线程是不能直接访问Ui组件的,例如:在另一个线程调用textView。setText(“23232”);在编译的时候是没有问题的,但是在运行时就会报错,所以这时候就要用到handler的函数,我们在这里可以理解为一个中介,子线程将信息绑定在handler上,handler将信息更新到主函数UI上,里面会用到callBack函数,具体代码里讲,万事俱备,只差将网络权限添加到你的手机上了,在AndroidMainfest.xml文件中,在
android:minSdkVersion="8"
android:targetSdkVersion="18" />后面添加网络允许代码,就是下面这一句
接下来,就是UI界面MainActivity.java代码如下:
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.app.Activity;
- import android.util.Log;
- import android.view.Menu;
- 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 {
- //聊天区域
- private TextView textMsgLog;
- //客户端处理线程
- private ClientThread clientThread;
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button btnSend=(Button)findViewById(R.id.btnSend);
- //聊天显示界面
- textMsgLog=(TextView)findViewById(R.id.textMsgLog);
- Log.i("test", "oooooooooooooo11111");
- //创建Handler对象,介于主线程和子线程一个代理,子线程ClientThread将要传递的数据通过
- //Handler传递给主进程UI,数据在UI上更新
- Handler.Callback callback=new Handler.Callback(){
- public boolean handleMessage(Message msg){
- //
- textMsgLog.append("服务器:" + msg.obj.toString() +
- "\n");
- return true;
- }
- };
- Handler handler=new Handler(callback);
- clientThread =new ClientThread(handler);
- clientThread.start();
- }
- //将文本输入框的发送给服务器
- public void send(View v){
- //得到输入框
- EditText editInput = (EditText)findViewById(R.id.editInput);
- //得到输入框中文字
- String msg = editInput.getText().toString();
- //调用,写到服务器上,返回成功
- boolean result = clientThread.sendText(msg);
- textMsgLog.append("我:"+msg+"\n");
- if(result){
- textMsgLog.append("我:"+msg+"\n");
- editInput.setText("");
- } else {
- Toast.makeText(this, "发送失败", Toast.LENGTH_LONG).show();
- }
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
#p#和客户端线程,也就是刚才说的子线程代码:
- ackage com.example.eetalk;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import android.os.Handler;
- import android.os.Message;
- public class ClientThread extends Thread {
- private Handler handler;
- private DataOutputStream dos;
- private DataInputStream dis;
- private Socket socket;
- public ClientThread(Handler handler) {
- this.handler = handler;
- }
- public void run() {
- try {
- connect();
- dos.writeInt(1);
- dos.writeInt(5);
- dos.write("hello".getBytes());
- while (true) {
- //读取服务器发过来的数据
- int msgType = dis.readInt();
- //
- System.out.println("121");
- //
- int len = dis.readInt();
- //
- byte[] bytes = new byte[len];
- dis.readFully(bytes);
- //
- String content = new String(bytes, "GB2312");
- Message msg = new Message();
- msg.what = 1;
- //
- msg.obj = content;
- //
- handler.sendMessage(msg);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- //close();
- }
- }
- private void connect() throws UnknownHostException, IOException {
- //
- socket = new Socket("172.27.35.3", 8888);
- //
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
- }
- private void close() {
- if (dis != null) {
- try {
- dis.close();
- } catch (IOException e) {
- }
- }
- if (dos != null) {
- try {
- dos.close();
- } catch (IOException e) {
- }
- }
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- }
- //发送到服务器的
- public boolean sendText(String content){
- try {
- //
- byte[] bytes = content.getBytes("GB2312");
- //
- dos.writeInt(1);
- //
- dos.writeInt(bytes.length);
- //
- dos.write(bytes);
- dos.flush();
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
- }
记住你的手机和你的电脑一定要在同一个局域网,这里可以看出手机的客户端做法与电脑是差不多的,上面手机客户端连接的ip地址是你的电脑连入的ipv4地址,可以在cmd命令里恰如ipconfig来搜寻。
做到这里,将你的app下载到手机,打开服务器,打开手机的应用程序,就可以聊天了,记住打开网络
美美聊天了:
这是服务器
这是手机客户端
做到这里,就可以和手机互发图片和文字啦,这是小编下期的实现目标 。