Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)

54 阅读6分钟

4.1使用TCP协议通信

android端实现:

[java] view plain copy

print ?

  1.     protected void connectServerWithTCPSocket() {  

  2.         Socket socket;  

  3.         try {// 创建一个Socket对象,并指定服务端的IP及端口号  

  4.             socket = new Socket(“192.168.1.32”, 1989);  

  5.             // 创建一个InputStream用户读取要发送的文件。  

  6.             InputStream inputStream = new FileInputStream(“e://a.txt”);  

  7.             // 获取Socket的OutputStream对象用于发送数据。  

  8.             OutputStream outputStream = socket.getOutputStream();  

  9.             // 创建一个byte类型的buffer字节数组,用于存放读取的本地文件  

  10.             byte buffer[] = new byte[4 * 1024];  

  11.             int temp = 0;  

  12.             // 循环读取文件  

  13.             while ((temp = inputStream.read(buffer)) != -1) {  

  14.                 // 把数据写入到OuputStream对象中  

  15.                 outputStream.write(buffer, 0, temp);  

  16.             }  

  17.             // 发送读取的数据到服务端  

  18.             outputStream.flush();  

  19.             /** 或创建一个报文,使用BufferedWriter写入,看你的需求 **/  

  20. //          String socketData = ”[2143213;21343fjks;213]”;  

  21. //          BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(  

  22. //                  socket.getOutputStream()));  

  23. //          writer.write(socketData.replace(“\n”, ” ”) + ”\n”);  

  24. //          writer.flush();  

  25.             /************************************************/  

  26.         } catch (UnknownHostException e) {  

  27.             e.printStackTrace();  

  28.         } catch (IOException e) {  

  29.             e.printStackTrace();  

  30.         }  

  31.     }  

protected void connectServerWithTCPSocket() {

Socket socket;

try {// 创建一个Socket对象,并指定服务端的IP及端口号

socket = new Socket("192.168.1.32", 1989);

// 创建一个InputStream用户读取要发送的文件。

InputStream inputStream = new FileInputStream("e://a.txt");

// 获取Socket的OutputStream对象用于发送数据。

OutputStream outputStream = socket.getOutputStream();

// 创建一个byte类型的buffer字节数组,用于存放读取的本地文件

byte buffer[] = new byte[4 * 1024];

int temp = 0;

// 循环读取文件

while ((temp = inputStream.read(buffer)) != -1) {

// 把数据写入到OuputStream对象中

outputStream.write(buffer, 0, temp);

}

// 发送读取的数据到服务端

outputStream.flush();

/** 或创建一个报文,使用BufferedWriter写入,看你的需求 **/

// String socketData = "[2143213;21343fjks;213]";

// BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(

// socket.getOutputStream()));

// writer.write(socketData.replace("\n", " ") + "\n");

// writer.flush();

/************************************************/

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

服务器端简单实现:

[java] view plain copy

print ?

  1. public void ServerReceviedByTcp() {  

  2.     // 声明一个ServerSocket对象  

  3.     ServerSocket serverSocket = null;  

  4.     try {  

  5.         // 创建一个ServerSocket对象,并让这个Socket在1989端口监听  

  6.         serverSocket = new ServerSocket(1989);  

  7.         // 调用ServerSocket的accept()方法,接受客户端所发送的请求,  

  8.         // 如果客户端没有发送数据,那么该线程就停滞不继续  

  9.         Socket socket = serverSocket.accept();  

  10.         // 从Socket当中得到InputStream对象  

  11.         InputStream inputStream = socket.getInputStream();  

  12.         byte buffer[] = new byte[1024 * 4];  

  13.         int temp = 0;  

  14.         // 从InputStream当中读取客户端所发送的数据  

  15.         while ((temp = inputStream.read(buffer)) != -1) {  

  16.             System.out.println(new String(buffer, 0, temp));  

  17.         }  

  18.         serverSocket.close();  

  19.     } catch (IOException e) {  

  20.         e.printStackTrace();  

  21.     }  

  22. }  

public void ServerReceviedByTcp() {

// 声明一个ServerSocket对象

ServerSocket serverSocket = null;

try {

// 创建一个ServerSocket对象,并让这个Socket在1989端口监听

serverSocket = new ServerSocket(1989);

// 调用ServerSocket的accept()方法,接受客户端所发送的请求,

// 如果客户端没有发送数据,那么该线程就停滞不继续

Socket socket = serverSocket.accept();

// 从Socket当中得到InputStream对象

InputStream inputStream = socket.getInputStream();

byte buffer[] = new byte[1024 * 4];

int temp = 0;

// 从InputStream当中读取客户端所发送的数据

while ((temp = inputStream.read(buffer)) != -1) {

System.out.println(new String(buffer, 0, temp));

}

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

4.2使用UDP协议通信

客户端发送数据实现:

[java] view plain copy

print ?

  1. protected void connectServerWithUDPSocket() {  

  2.     DatagramSocket socket;  

  3.     try {  

  4.         //创建DatagramSocket对象并指定一个端口号,注意,如果客户端需要接收服务器的返回数据,  

  5.         //还需要使用这个端口号来receive,所以一定要记住  

  6.         socket = new DatagramSocket(1985);  

  7.         //使用InetAddress(Inet4Address).getByName把IP地址转换为网络地址    

  8.         InetAddress serverAddress = InetAddress.getByName(”192.168.1.32”);  

  9.         //Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName(“192.168.1.32”);    

  10.         String str = ”[2143213;21343fjks;213]”;//设置要发送的报文    

  11.         byte data[] = str.getBytes();//把字符串str字符串转换为字节数组    

  12.         //创建一个DatagramPacket对象,用于发送数据。    

  13.         //参数一:要发送的数据  参数二:数据的长度  参数三:服务端的网络地址  参数四:服务器端端口号   

  14.         DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);    

  15.         socket.send(packet);//把数据发送到服务端。    

  16.     } catch (SocketException e) {  

  17.         e.printStackTrace();  

  18.     } catch (UnknownHostException e) {  

  19.         e.printStackTrace();  

  20.     } catch (IOException e) {  

  21.         e.printStackTrace();  

  22.     }    

  23. }  

protected void connectServerWithUDPSocket() {

DatagramSocket socket;

try {

//创建DatagramSocket对象并指定一个端口号,注意,如果客户端需要接收服务器的返回数据,

//还需要使用这个端口号来receive,所以一定要记住

socket = new DatagramSocket(1985);

//使用InetAddress(Inet4Address).getByName把IP地址转换为网络地址

InetAddress serverAddress = InetAddress.getByName("192.168.1.32");

//Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName("192.168.1.32");

String str = "[2143213;21343fjks;213]";//设置要发送的报文

byte data[] = str.getBytes();//把字符串str字符串转换为字节数组

//创建一个DatagramPacket对象,用于发送数据。

//参数一:要发送的数据 参数二:数据的长度 参数三:服务端的网络地址 参数四:服务器端端口号

DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);

socket.send(packet);//把数据发送到服务端。

} catch (SocketException e) {

e.printStackTrace();

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

客户端接收服务器返回的数据:

[java] view plain copy

print ?

  1. public void ReceiveServerSocketData() {  

  2.     DatagramSocket socket;  

  3.     try {  

  4.         //实例化的端口号要和发送时的socket一致,否则收不到data  

  5.         socket = new DatagramSocket(1985);  

  6.         byte data[] = new byte[4 * 1024];  

  7.         //参数一:要接受的data 参数二:data的长度  

  8.         DatagramPacket packet = new DatagramPacket(data, data.length);  

  9.         socket.receive(packet);  

  10.         //把接收到的data转换为String字符串  

  11.         String result = new String(packet.getData(), packet.getOffset(),  

  12.                 packet.getLength());  

  13.         socket.close();//不使用了记得要关闭  

  14.         System.out.println(”the number of reveived Socket is  :” + flag  

  15.                 + ”udpData:” + result);  

  16.     } catch (SocketException e) {  

  17.         e.printStackTrace();  

  18.     } catch (IOException e) {  

  19.         e.printStackTrace();  

  20.     }  

  21. }  

public void ReceiveServerSocketData() {

DatagramSocket socket;

try {

//实例化的端口号要和发送时的socket一致,否则收不到data

socket = new DatagramSocket(1985);

byte data[] = new byte[4 * 1024];

//参数一:要接受的data 参数二:data的长度

DatagramPacket packet = new DatagramPacket(data, data.length);

socket.receive(packet);

//把接收到的data转换为String字符串

String result = new String(packet.getData(), packet.getOffset(),

packet.getLength());

socket.close();//不使用了记得要关闭

System.out.println("the number of reveived Socket is :" + flag

  • "udpData:" + result);

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

服务器接收客户端实现:

[java] view plain copy

print ?

  1. public void ServerReceviedByUdp(){  

  2.     //创建一个DatagramSocket对象,并指定监听端口。(UDP使用DatagramSocket)    

  3.     DatagramSocket socket;  

  4.     try {  

  5.         socket = new DatagramSocket(10025);  

  6.         //创建一个byte类型的数组,用于存放接收到得数据    

  7.         byte data[] = new byte[4*1024];    

  8.         //创建一个DatagramPacket对象,并指定DatagramPacket对象的大小    

  9.         DatagramPacket packet = new DatagramPacket(data,data.length);    

  10.         //读取接收到得数据    

  11.         socket.receive(packet);    

  12.         //把客户端发送的数据转换为字符串。    

  13.         //使用三个参数的String方法。参数一:数据包 参数二:起始位置 参数三:数据包长    

  14.         String result = new String(packet.getData(),packet.getOffset() ,packet.getLength());    

  15.     } catch (SocketException e) {  

  16.         e.printStackTrace();  

  17.     } catch (IOException e) {  

  18.         e.printStackTrace();  

  19.     }    

  20. }  

最后

在此为大家准备了四节优质的Android高级进阶视频:

架构师项目实战——全球首批Android开发者对Android架构的见解

链接:GitHub 免费获取!

附相关架构及资料

image.png

领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。