这篇博客呢主要是两个手机进行 Socket 通信案例的分析
(话说老娘也算写了几篇博客,为什么访问量就是少的可怜呢……)
首先是这个案例可以实现什么:
它包含两个工程,一个服务端,一个客户端,服务端的工程里面有个按钮,是打开服务端链接,客户端有两个按钮,一个是链接服务端,一个是发送数据
什么是 TCP/IP 协议,什么是 Socket ???
网络由下往上分为:
物理层–
数据链路层–
网络层– IP协议
传输层– TCP协议
会话层–
表示层和应用层– HTTP协议
TCP/TP协议简称 网络传输层,主要用来传输数据
为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与 TCP/IP 协议交互提供了套接字( Socket )接口。应用层可以和传输层通过 Socket 接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
这个大神讲的挺清楚的:http://www.cnblogs.com/iOS-mt/p/4264675.html
为了让APP正确运行,必须要保证两个设备的网络属于同一个网端 (连接在了同一个WiFi上面)
服务端一共做了两件事:
1.打开服务端等待客户端链接
2.接收客户端信息并反馈给客户端信息
这两个功能的实现我都把它封装到两个内部类里面了
下面是这个工程的步骤
1.创建服务端 Socket 监听服务端的链接
等待客户端的链接是一个耗时操作,所以要放到子线程
class ServerSocketThread extends Thread {
@Override
public void run() {
try {
//创建服务端Socket
ServerSocket serverSocket = new ServerSocket();
//绑定客户端(因为是在同一个机子上访问,所以IP地址一样,直接是127.0.0.1)
serverSocket.bind(new InetSocketAddress("10.232.9.241", 1234));//服务端的IP地址
//一直等待客户端链接
while (true) {
Log.e("TAG", "server_wait");
//链接客户端
Socket socket = serverSocket.accept();
//这是一个监听客户端发送信息,并向客户端反馈的方法,(后面讲到)
connected(socket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤:
创建一个serverSocket 为它绑定IP地址和端口号,IP地址那一行需要更改
不断地while循环 监听客户端的链接
注意:创建SeverSocket的时候IP地址要是服务端的IP地址(我在这里跌倒过…)
最后是可以打印出以下的log日志的:
2.接收客户端的信息并向客户端反馈
同样这里要开启一个子线程,因为要不断地接收客户端的信息,所以这个也定义在内部类中了
class ConnectThread extends Thread {
Socket socket;//得到连接的客户端的Socket
InputStream in = null;
OutputStream out = null;
public ConnectThread(Socket socket) {
this.socket = socket;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];//字节数组承载读到的字节
int bytes ;
//等待另一端发送的数据
try {
while ((bytes = in.read(buffer)) != -1) {
Log.e("TAG", "server_read:" + new String(buffer, 0, bytes));
String data = "server_read_success";
write(data.getBytes());//向客户端写入反馈的方法
}
} catch (IOException e) {
e.printStackTrace();
}
}
因为要接收和向客户端发送信息所以必须得到客户端 socket 对象的输入输出流,所以在构造方法中要传入和服务端结合的客户端 socket
这样就可以读到客户端发来的信息系了
那么怎么给客户端一个反馈呢 ???—-就是向客户端发出信息
我把这个也放到了和服务端通信的内部类中了
//向另一端写数据的操作
public void write(byte[] buffer) {
try {
out.write(buffer);
Log.e("TAG", "server_write " + new String(buffer));
} catch (IOException e) {
e.printStackTrace();
}
}
最后是关闭流,只需要关闭 socket 即可
//关闭的方法
public void cancle() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
这个通信类就写完了,里面包含开启
子线程(run方法中)不断地接收客户端发来的信息
向客户端写入信息
关闭流的操作
3.connected(Socket socket);方法的实现
在上面第一个内部类绑定好客户端后有个链接客户端的方法,这个方法主要是做对客户端消息的监听和反馈,对!就是对上面第二个类的实例化之类的操作
private void connected(Socket socket) {
if (connectThread != null) {
connectThread.cancle();
connectThread = null;
}
connectThread = new ConnectThread(socket);
connectThread.start();
Log.e("TAG", "connect success");
}
把这个方法放到第一个绑定客户端的类里面就行了
最后最后!! 别忘了 new ServerSocketThread().start();
源码在这里 :
谢谢观看~