• 实现聊天界面的代码


    可能现在很多应用中都会用到两个人活着多人互动的界面,当然,对于这个界面,我们别无选择的都会用到客户端以及服务端的交互。

    这里主要的思路就是通过客户端接受用户的输入,然后,我们把输入的值通过一个请求发送给服务端,然后再通过一个方式得到服务端返回的数据,当然,这里想要不停的接受客户端的访问,所以在服务端我们必须要把条件设为true

    这里我们做一个简单的客户端界面,当然,这里我们也可以做成像QQ聊天界面那样的界面,然后可以做成一个多人聊天室。(网络聊天室)。

     

    /***

     * 

     * @author William 这里我们要演示的是多线程聊天功能

     * 

     * */

    public class AndroidThreadClientActivity extends Activity {

    /** Called when the activity is first created. */

    // define a key这里我们就是给客户端一个端口,然后让他们进行交互

    public static final int PORT = 8080;

    //这里的ip地址是在无网的状态下也可以进行连接的ip,那么大家就该知道是什么了吧(虚列机的ip

    public static final String HOST = "10.0.2.2";

    private EditText sentText;

    private EditText getText;

    Socket s;

    // create a visible t

    // 创建消息对象

    Handler handler;

    String get_text;

    // 设置菜单的listView留言人的数组

     

    // 输出流对象

    OutputStream output;

     

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // 构建视图控件

    getText = (EditText) findViewById(R.id.get);

    sentText = (EditText) findViewById(R.id.send);

    // 立即与服务端连接

    try {

    s = new Socket(HOST, PORT);

     

    System.out.println("he is " + s.getInetAddress() + "的用户--->1");

     

    output = s.getOutputStream();

     

    } catch (UnknownHostException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    // sendBtn.setOnClickListener((android.view.View.OnClickListener) this);

    // 使用类方法创建Handler

    handler = new Handler() {

     

    @Override

    public void handleMessage(Message msg) {

    /* super.handleMessage(msg); */

    // 判断是否是子线程传过来的信息

    if (msg.what == 3) {

    // 将服务器端的消息追加的edittext控件进行显示

    System.out.println("这里我是去读线程消息传过来的值------>6");

    get_text = msg.obj.toString();

    getText.append(get_text);

    // 启动子线程,每个线程处理对应的socket

     

    MyThread my = new MyThread(s, handler);

    new Thread(my).start();

    System.out.println("我已经启动了线程clientthread----------->5");

     

     

    } else {

     

    System.out.println("不好意思,线程获取错误");

    }

     

    }

    };

     

    }

     

    public void onAction(View v) {

    // 将输入文本框的文本信息写出流

    try {

    System.out.println("我写的内容是" + sentText.getText().toString());

    output.write((sentText.getText().toString() + " ")

    .getBytes("utf-8"));

    // output.write(sentText.getText().toString() .getBytes());

    System.out.println(sentText.getText().toString());

     

    } catch (UnsupportedEncodingException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    sentText.setText("");

     

    }

     

    }

    这里我们把消息实现消息的线程建立成了一个外部类,当然,这里我们也可以建立成一个内部类:

     

    import android.os.Handler;

    import android.os.Message;

    //这里我开始也以为会有一些问题,那就是我们见过的都是继承Thread,而这里呢?我们这里是直接继承了runable

    public class MyThread  implements Runnable{

     

    private Socket s;

    private Handler handler;

    BufferedReader br = null;

    String str;

    /**

     * to create the funcation

     * */

    public MyThread(Socket s, Handler h) {

     

    this.s = s;

    this.handler = h;

    try {

    //这里我开始是想要进行测试的,结果发现有问题,所以,还是用下面这种的吧。

    一种:

    // // deine a inputstream

    // InputStream ip = s.getInputStream();

    // // define a byte

    // byte[] mByte = new byte[1024];

    // // input the byte int the

    // ip.read(mByte);

    //二种:

    br = new BufferedReader(new InputStreamReader(

    s.getInputStream(), "utf-8"));

    System.out.println("str is ------>----->2"+br);

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    @Override

    public void run() {

     

    String content = "haha";

    System.out.println("我在run里面了------------>3");

     

    // TODO Auto-generated method stub

    // to read the content

    //这里我是用的true,当然我只是为了测试,你们就大可不必这样了

    while (true) {

    System.out.println("我在run里面了------------>4");

    //Message message = handler.obtainMessage();

    Message message=new Message();

    message.what = 3;

    message.obj = content;

    handler.sendMessage(message);

     

    }

     

    }

    以上就是一个实现一个简单聊天的客户端过程。

    当然,这里呢,我也将服务端的代码贴了出来:

    package cn;

     

    import java.io.IOException;

    import java.net.ServerSocket;

    import java.net.Socket;

    import java.util.ArrayList;

    import java.util.List;

     

    public class ThreadServer {

     

    // 定义保存所有socket里面的的list

    public static List<Socket> socketList = new ArrayList<Socket>();

     

    /**

     * 

     * @author Wiuizm

     * */

    public static void main(String[] args) {

     

    // 创建serversocket对象,使用端口8080

    try {

    System.out.println("我在服务端的main方法里面");

    ServerSocket ss = new ServerSocket(8080);

     

    // 不断的轮询,然后接受客户端的访问

    while (true) {

    // 创建socket对象

    Socket s = ss.accept();

    System.out.println("he is "+s.getInetAddress()+"的用户");

    socketList.add(s);

    System.out.println(socketList);

    // 客户端连接后,我们启动第一条线程,然后开始为客户端服务

    new Thread(new serverThreas(s)).start();

     

    }

     

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

    //这里也可以建立一个内部类或者外部类,当然,我这里是建立了一个外部类,方便看吧,老师也曾经说过,我们把能分开的就分开吧,这样在每一个类里面就不会看到太多的代码量。

     

    //这里是一个外部线程类:

    public class serverThreas implements Runnable{

     

    // 定义当前处理线程的socket

    Socket s = null;

    // 该线程处理的socket所对应的输入流

    BufferedReader br = null;

     

    /***

     * 构造党法

     * 

     * */

     

    public serverThreas(Socket s) {

    System.out.println("我在socketthread里面");

    this.s = s;

    // 初始化socket对应的输入流

    try {

    br = new BufferedReader(new InputStreamReader(

    s.getInputStream(), "utf-8"));

    System.out.println(br);

    } catch (UnsupportedEncodingException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

     

    @Override

    public void run() {

    // TODO Auto-generated method stub

    String content = null;

    while ((content = readMessageFormClient()) != null) {

     

    // 遍历socketlist中的每个socket,将读取到的内容行每个socket发送一次

    for (Socket s : ThreadServer.socketList) {

    // 创建输出流对象

    OutputStream output;

    try {

    output = s.getOutputStream();

    output.write((content + " ").getBytes("utf-8"));

    output.flush();

    output.close();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

     

    }

    }

     

    }

    private String readMessageFormClient() {

     

    try {

    System.out.println("this content is ----->"+br.readLine());

    return br.readLine();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    // 如果发生异常

    ThreadServer.socketList.remove(s);

    e.printStackTrace();

    }

    return null;

     

    }

     

    }

    好了,现在客户端和服务端我们都算有一点思路了,不知道大家看了有清晰一点没?如果有什么不对劲的地方,希望大家还是狠狠的提出来,谢谢。

     

     

     

     

    一切只是为了充实自己!!stay hungry and stay foolish!!
  • 相关阅读:
    高斯核函数的代码体现
    程序编译
    DoH
    随笔1
    获取节点值的方式
    DOM解析XML
    URLConnection发送请求,并接收数据
    myeclipse编译后的jsp文件存放位置
    各种中文乱码
    各种提交的区别
  • 原文地址:https://www.cnblogs.com/Catherine-Brain/p/3543770.html
Copyright © 2020-2023  润新知