一、简介 

即时通讯 : IM  instant messager

是通过消息通道传输消息对象

消息通道由TCP/IP UDP实现

TCP/UDP传输消息的时候,封装上IP,

IP  网络上电脑 的编号

port 网络程序的编号 


二、TCP与UDP的区别 

Tcp UDP


大文件 限定大小 ,64K

可靠,三次握手 不可靠

面向连接 不面向连接

效率低 效率高


三、三次握手

第一次     客户端---(消息)--服务端

第二次     服务端-- (什么时候)-- 客户端

第三次     客户端--(现在)-- 服务端

Android-即时通训_android开发

四、即时通讯的觉方式

1. 在线直传: 不经过服务器,直接从客户端传向客户端

2. 在线代理: 经过服务器,中转,到达目标中账号

3. 离线代理: 经过服务器,若对方不在线,将数据储存在服务端,对应账号上线后再传输数据 

4. 离线扩理: 将暂存服务器端的数据以其它方式(邮件,短信等)方式传输给目标

五、请求服务器的基本代码逻辑

package com.administrator.imtest;

import android.app.Activity;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/**
* Created by Administrator on 2015/11/9.
*/
public class SocketConnect extends Activity {


/**
* 上传信息的url
*
*/
private String url="";
/**
* 服务器的url
*
*/
private String HOST =url;
/**
* 服务器端口号
*
*/
private int POST = 8080;

/**
* 连接服务器,信息交互的过程
*
*/
private void function(){



new Thread() {
@Override
public void run() {

try {
/**
* 创建一个连接通道
*
*/
Socket socket = new Socket(HOST, POST);
/**
* 读取信息的流
*/

final DataInputStream dataInputStream = new DataInputStream(socket .getInputStream());
/**
* 写入信息的流
*/
DataOutputStream dataOutputStream = new DataOutputStream(socket .getOutputStream());

//上传数据
dataOutputStream.writeUTF(xml);
dataOutputStream.flush();

new Thread() {
@Override
public void run() {
while (true){

try {
/**
* 等待服务器返回的消息
* 注意这里不是死循环
*/
String xml = dataInputStream.readUTF();

} catch (IOException e) {
e.printStackTrace();
}


}
}
}.start() ;


} catch (IOException e) {
e.printStackTrace();
}

}
}.start() ;




}


}




六、与服务器进行数据交互的核心代码 



public class MessageConnection extends Thread {


/**
* 基本实现步骤
* 1. 连接到服务端
* 2. 发送消息
* 3. 接收消息
* 4. 断开与服务器的连接
*/

//ip地址
private String HOST = "";
//端口号
private int POST = 00;


private Socket mSocket;
private DataInputStream reader = null;
private DataOutputStream writer = null;


/**
* 设置更改服务器地址与端口的方法
*/
private String getHost() {
return HOST;
}

public void setHOST(String host) {
this.HOST = host;
}

private int getPost() {
return POST;
}

public void setPOST(int post) {
this.POST = post;
}

/**
* 创建连接
*/
public void connect() {
if (mSocket == null) {
try {
mSocket = new Socket(getHost(), getPost());
//获取服务器返回的流
reader = new DataInputStream(mSocket.getInputStream());
//获取输出流
writer = new DataOutputStream(mSocket.getOutputStream());
mIsRunThread = true;
//开启线程
start();
} catch (IOException e) {
e.printStackTrace();
}

}
}


/**
* 发送消息
*
* @param mesge
*/
public void sendMessage(String mesge) {
try {
writer.writeUTF(mesge);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}

}


/**
* 声明接口
*/

public static interface OnMessageReceiveListener {
/**
* 声明接收信息对象的抽象方法
*/
public void onReceiveMessage(MessageBean messageBean);
}


/**
* 有多个消息的话,用于储存消息监听的集合
*
* @param savedInstanceState
*/
private ArrayList<OnMessageReceiveListener> mMessageBeanArrayList = new ArrayList<>();

/**
* 添加消息监听的方法
*/
public void addOnMessageReceiveListener(OnMessageReceiveListener onMessageReceiveListener) {
mMessageBeanArrayList.add(onMessageReceiveListener);
}

/**
* 移除消息监听的方法
*/
public void removeOnMessageReceiveListener(OnMessageReceiveListener onMessageReceiveListener) {
mMessageBeanArrayList.remove(onMessageReceiveListener);
}

/**
* 用于判断是否打开子线程的方法
*/
private boolean mIsRunThread = true;

@Override
public void run() {
super.run();
while (mIsRunThread) {
try {
String xml = reader.readUTF();
MessageBean messageBean = new MessageBean();
messageBean = (MessageBean) messageBean.fromXml(xml);
if (messageBean != null) {
for (OnMessageReceiveListener listener : mMessageBeanArrayList) {
listener.onReceiveMessage(messageBean);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


/**
* 断开连接
*
* @throws IOException
*/

public void disConnect() {
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}

stop();
mIsRunThread = false;


}
}
}



七、提交用户名与密码到服务器进行登录验证



package com.administrator.imtest;

import android.app.Activity;
import android.os.Bundle;

import com.administrator.imtest.bean.MessageBean;
import com.administrator.imtest.util.MessageConnection;

public class MainActivity extends Activity {

private MessageConnection mMessageConnection;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
/**
* 向服务端上传数据下读取数据
*/

/**
* 建立连接,初始化消息通道
*
*/
new Thread(
new Runnable() {
@Override
public void run() {
mMessageConnection = new MessageConnection();
/**
*添加消息接收器,监听器
*/
mMessageConnection.addOnMessageReceiveListener(mOnMessageReceiveListener);
mMessageConnection.connect();
}
}).start();

}


/**
* xml是已经封装了登录信息的
* 发送数据的方法
*/
private void sendMessage(String xml) {
if (mMessageConnection != null) {
mMessageConnection.sendMessage(xml);
}
}

/**
* 关闭通道,关闭连接
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (mMessageConnection != null) {
mMessageConnection.disConnect();
/**
*移除消息监听器
*/
mMessageConnection.removeOnMessageReceiveListener(mOnMessageReceiveListener);
}
}


/**
* 调用 接收消息的接口
*/
private MessageConnection.OnMessageReceiveListener mOnMessageReceiveListener = new MessageConnection.OnMessageReceiveListener() {
@Override
public void onReceiveMessage(MessageBean messageBean) {

/**
* 进行判断,如果果提交的用户名正确 那么就跳转到到好友列表
*
*/

}
};


}