美文网首页产品汪的日常干货程序员
Android即时通信软件设计(一)(网络通信)

Android即时通信软件设计(一)(网络通信)

作者: 超低空 | 来源:发表于2014-05-17 16:05 被阅读7390次

    ——客户机、服务器连接通信

    最近刚做完一个基于Android的即时通信的项目工程,主要完成类似于QQ群的功能。项目涉及的知识面比较广,都是在网络通信上很实用的技术,非常适合初学者学习。其中也是遇到了各种错误、异常。在解决的过程中自己也收获了不少。在此分几个部分简述一下我的调试过程,也和大家分享一下我的收获,希望对大家有帮助。

    所要了解的主要知识点:

    • TCP/IP网络协议
    • 文件IO流
    • 二进制IO流
    • Activity的生命周期
    • Android多媒体开发(相机、媒体播放器)
    • Android Intent的使用
    • 多线程控制
    • Handler对象
    • ListView类

    以上是针对项目归纳的几个主要的知识点,接下来我会按照相关知识点分几篇文章来介绍整个项目过程。

    一、终端的网络连接

    既然是通信,首先要调通的就是网络连接。这里采用TCP/IP协议,使用JAVA的socket对象很容易实现。客户端代码如下:

    final int PORT = 6666;
            try
            {
                socket = new Socket();
                socket.connect(new InetSocketAddress("220.181.111.85",PORT), 3000);
                sendMsg(CONNECT_SUCCESS);
            } catch (Exception e)
            {
                sendMsg(CONNECT_FAILED);
            }
        ```
    这里新建一个Socket对象,然后Socket.connect会去连接指定IP地址的相应端口,设置超时时间为3000 ms。
    
    服务器端连接代码如下:
    

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;

    public class Main
    {
    public static ArrayList<Socket> socketList = new ArrayList<Socket>();

    public static void main(String[] args) throws IOException
    {
        @SuppressWarnings("resource")
        ServerSocket ss = new ServerSocket(6666);
        String ip = InetAddress.getLocalHost().getHostAddress();
        System.out.println(ip);
        while (true)
        {
            Socket s = ss.accept();
            socketList.add(s);
            new Thread(new ServerThread(s)).start();                  //启动服务器服务线程,主要用于接收、发送数据
        }
    }
    

    }

    和客户端一样,首先创建socket对象。然后Socket.accept()阻塞式等待连接,一旦有客户端连接,就会加入到socketList中(相当于登记客户端)。这样就完成了多个客户的连接。
    
    **注意**
    理论上Socket的端口可以任意指定0~65535中的任意一个,但是为了避免冲突,尽量选用1024以上的端口,这样可以避免占用。
    
    
    #####二、接受和发送对象
    在服务器与客户端建立连接之后就可以相互传送数据了。由于考虑到传送的不同数据的兼容问题,这里我采用了对象传输流(ObjectOutputStream / ObjectInputStream)。传输过程相比连接过程稍微复杂一点,大致流程如下:
    >1.通过Socket.getOutputStream()方法获取该Socket对象的OutputStream。
    2.创建ObjectOutputStream用于发送对象。
    3.调用ObjectOutputStream的Writexxx()方法写入xxx类型的数据。
    4.调用flush()方法清空数据流,完成本次发送。
    
    相关代码如下(两端收发代码保持统一):
    

    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.io.StreamCorruptedException;

    public class DataTransmission //收发数据类
    {
    static int revType;

    /**
    send用于发送数据
    data:表示要发送的数据对象
    type:表示要发送的对象的类型
    */
    public void send(Object data,int type) throws IOException
    {
    OutputStream os = ClientThread.socket.getOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(os);
    out.writeInt(type);
    out.writeObject(data);
    out.flush();
    }

    /**
    rev用于接收数据
    */
    public Object rev() throws StreamCorruptedException, IOException,
    ClassNotFoundException
    {
    ObjectInputStream in = new ObjectInputStream(
    ClientThread.socket.getInputStream());
    revType = in.readInt();
    return in.readObject();
    }
    }

    
    #####三、断开连接
    程序中涉及到的并不是两点通信,而对于多机通信而言,随时都允许有用户离线,这时候就需要在用户登记表中除去该用户。
    这里需要在服务器上完成,登记的时候是在建立的socketList中注册的,所以除去也需要在这个对象中完成。代码实现如下:
    

    public Object getObj()
    {
    Object obj;
    try
    {
    obj = data.rev(); //用于接收数据并且将数据返回,
    return obj;
    } catch (Exception e)
    { //如果有用户离线,则进入异常,随后在List中删除该socket对象
    Main.socketList.remove(socket);
    System.out.println("remove success");
    }
    return null;
    }

    这样就完成了对用户离线的记录,sockeList里面存放的始终是在线的用户。
    
    网络连接是通信工具最基本的功能,也是本次开发最初期的任务。至此已经完成了基本的网络通信,接下来我会继续和大家分享余下的各个功能模块。。。
    
    **持续更新中....**
    
    完整源代码地址:
    > http://github.com/hust-MC/Instance-Message
    
    
    

    相关文章

      网友评论

      • f4daeab6d9fc:这个即时通信没有再去完善了吗??
        是不是效果不太理想了??
      • 超低空:@minichen :relieved: 那就根据不同服务器的操作系统来看了,我用的windows server 2003。还没测试过连接上限
      • minichen: @超低空 我说的是服务端。客户端不用考虑连接数的。
      • 超低空:@minichen 暂时没有对这个进行过测试,Android系统好像没有硬性的连接数限制,只要能够在int范围内应该就可以。
      • minichen: @超低空 一个server端进程能接受的TCP连接数是有限制的,这和硬件无关,与操作系统有关。有没测试过上限?
      • 超低空:@minichen 目前没有设置上限,主要是受到硬件设备的限制。也可以通过软件设置上限。
      • minichen:server端可以承受多少个连接?

      本文标题:Android即时通信软件设计(一)(网络通信)

      本文链接:https://www.haomeiwen.com/subject/bfgrtttx.html