一、简介
即时通讯 : IM instant messager
是通过消息通道传输消息对象
消息通道由TCP/IP UDP实现
TCP/UDP传输消息的时候,封装上IP,
IP 网络上电脑 的编号
port 网络程序的编号
二、TCP与UDP的区别
Tcp UDP
大文件 限定大小 ,64K
可靠,三次握手 不可靠
面向连接 不面向连接
效率低 效率高
三、三次握手
第一次 客户端---(消息)--服务端
第二次 服务端-- (什么时候)-- 客户端
第三次 客户端--(现在)-- 服务端
四、即时通讯的觉方式
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) {
/**
* 进行判断,如果果提交的用户名正确 那么就跳转到到好友列表
*
*/
}
};
}