您的位置:首页 > 移动开发 > Android开发

Android即时通讯--仿QQ即时聊天:(一)初识Socket

2016-02-27 10:19 573 查看

1、即时通讯简介

即时通讯(Instant Messaging,简称IM)是一个终端服务,允许两人或者多人通过网络即时传递文字讯息、档案、语音等。简单的概括就是发送消息时,只要对方在线,就能立即接收到消息。即时通讯的底层使用socket实现。即时通讯按使用用途分为企业即时通讯和网站即时通讯,根据装载的对象又可分为手机即时通讯和PC即时通讯,手机即时通讯代表是微信、QQ、短信、陌陌。
在这篇文章中,利用Socket+IO流+Thread线程+监听器的知识,简单的实现了点对点的即时通讯,功能比较丑陋,但是底层实现原理是非常重要的,希望这篇文章对初学者能有所帮助,大神勿进、勿喷。
本项目的效果图如下









2、初识Socket

所谓的Socket通常称为套接字,用于描述IP地址和端口,是一个通信连的句柄。应用程序通过套接字向网络发送请求,或者应答网络请求。Socket套接字,其实就是Java对TCP/IP的实现,Socket和ServerSocket可以形象的比喻为插头和插座,ServerSocket插座提供电源,是服务端;Socket插头要得到电源,是客户端。Socket网络通讯传输数据的过程就好比插头获取插座电源的过程。
服务端:利用ServerSocket监听指定的端口,等待客户端的连接请求,客户端建立连接之后,产生会话,完成会话后,关闭连接。
客户端:利用Socket向网络上的某一个端口发出连接请求,一旦连接成功,产生会话,完成回话之后,关闭连接。
服务端接收消息代码
/**
* socket服务端
*
* @author ZHY
*
*/
public class ServerSocketTest {
public static void main(String[] args) throws IOException {
final ServerSocket server = new ServerSocket(8090);
System.out.println("服务器已经启动" + server);
// 开启一个线程,时刻监听客户端发送过来的连接请求
new Thread() {
public void run() {
super.run();
while (true) {
try {
Socket client = server.accept();// 服务器接收到链接进来的客户端
System.out.println("有客户端链接进来" + client);
// 处理接收到的数据
// 由于服务器不知道客户端什么时候发送数据过来,所以要创建等待线程,时刻等待处理客户端发送过来的额数据
WaitThread waitThread = new WaitThread(client);
waitThread.start();
} catch (IOException e) {
e.printStackTrace();
}

}
}
}.start();

}

// 等待线程
public static class WaitThread extends Thread {
private Socket client;
// 服务端使用输入流读取数据
private DataInputStream reader;

// 在构造等待线程的时候,给客户端赋值
public WaitThread(Socket client) {
super();
this.client = client;
}

public void run() {
super.run();
// 循环等待处理数据
while (true) {
if (reader == null) {
// 根据客户端发来的输入流,创建服务器读取数据的流reader
try {
reader = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
try {
String msg = reader.readUTF();
System.out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}

}

}
}

}
客户端发送消息代码

/**
* Socket客户端
* @author ZHY
*
*/
public class MainActivity extends Activity {
private Button client;
private Button send;
private Socket socket;
private DataOutputStream writer;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
client = (Button) findViewById(R.id.client);// 连接服务器
send = (Button) findViewById(R.id.send);// 发送数据

client.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
// 连接服务器,与网络有关,要在子线程中

new Thread() {
@Override
public void run() {
super.run();
try {
// 创建socket,连接服务器
socket = new Socket("192.168.0.148", 8090);

} catch (Exception e) {
e.printStackTrace();
}
}
}.start();

}
});

send.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
// 客户端向服务端发送消息,通过输出流,在子线程中
new Thread() {
@Override
public void run() {
super.run();
if (socket == null) {
// 创建socket,连接服务器
try {
socket = new Socket("192.168.0.148", 8090);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 已经建立了连接
if (writer == null) {
try {
writer = new DataOutputStream(socket
.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// writer也不是空
try {
writer.writeUTF("我是客户端发送的数据" + socket);
} catch (IOException e) {
e.printStackTrace();
}

}
}.start();
}
});

}
}
客户端与服务端的数据交互会话示意图



至此,Socket的基本原理已经交代清楚,了解了底层实现的原理,相信对即时通讯的理解将更深一步。
PS:如果有什么不妥的地方希望大神指出,共同学习进步!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: