Android完全支持JDK本身的TCP、UDP网络通信API,也可使用ServerSocket、Socket来建立基于TCP/IP协议的网络通信,还可使用DatagramSocket、Datagrampacket、MulticastSocket来建立基于UDP协议的网络通信。Android也支持JDK提供的URL、URLConnection等网络通信API。
Socket是对TCP/IP协议的封装,是一个调用接口API。在TCP/IP协议中主要有Socket类型的流套接字StreamSocket和数据报套接字DatagramSocket。
Java中能接受其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端拿到Socket连接,如果没有连接,它将一直处于等待状态。
ServerSocket ss =new ServerSocket(30000);
while(true){
Socket s = ss.accept();
……
}
使用步骤:
public class SocketServer {
public static void main(String[] args) throws IOException {
//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(12345);
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
Socket socket = null;
//2.调用accept()等待客户端连接
System.out.println("~~~服务端已就绪,等待客户端接入~,服务端ip地址: " + ip);
socket = serverSocket.accept();
//3.连接后获取输入流,读取客户端信息
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
OutputStream os=null;
PrintWriter pw=null;
is = socket.getInputStream(); //获取输入流
isr = new InputStreamReader(is,"UTF-8");
br = new BufferedReader(isr);
String info = null;
while((info=br.readLine())!=null){
//循环读取客户端的信息
System.out.println("客户端发送过来的信息" + info);
}
socket.shutdownInput();//关闭输入流
socket.close();
}
}
构造器中指定远程主机时既可使用InetAddress来指定,也可直接使用String对象来指定,但程序通常使用String对象来指定远程IP地址。
Socket s = new Socket("192.168.1.88",30000);
使用步骤:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_accept = (Button) findViewById(R.id.btn_accept);
btn_accept.setOnClickListener(this);
}
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
try {
acceptServer();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
private void acceptServer() throws IOException {
//1.创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("172.16.2.54", 12345);
//2.获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream();//字节输出流
PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
//获取客户端的IP地址
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
pw.write("客户端:~" + ip + "~ 接入服务器!!");
pw.flush();
socket.shutdownOutput();//关闭输出流
socket.close();
}}
}}
注:Android已经不允许在UI线程中建立网络连接。
在Android中访问互联网,要为该应用赋予访问互联网的权限:
UDP以数据报作为数据的传输载体,在进行传输时首先要把传输的数据定义成数据报(Datagram),在数据报中指明数据要到达的Socket(主机IP地址和端口号),然后再将数据以数据报的形式发送出去。
使用步骤:
public class UPDServer {
public static void main(String[] args) throws IOException {
/*
* 接收客户端发送的数据
*/
// 1.创建服务器端DatagramSocket,指定端口
DatagramSocket socket = new DatagramSocket(12345);
// 2.创建数据报,用于接收客户端发送的数据
byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
DatagramPacket packet = new DatagramPacket(data, data.length);
// 3.接收客户端发送的数据
System.out.println("****服务器端已经启动,等待客户端发送数据");
socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
// 4.读取数据
String info = new String(data, 0, packet.getLength());
System.out.println("我是服务器,客户端说:" + info);
/*
* 向客户端响应数据
*/
// 1.定义客户端的地址、端口号、数据
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "欢迎您!".getBytes();
// 2.创建数据报,包含响应的数据信息
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
// 3.响应客户端
socket.send(packet2);
// 4.关闭资源
socket.close();
}
}
使用步骤:
public class UDPClient {
public static void main(String[] args) throws IOException {
/*
* 向服务器端发送数据
*/
// 1.定义服务器的地址、端口号、数据
InetAddress address = InetAddress.getByName("localhost");
int port = 8800;
byte[] data = "用户名:admin;密码:123".getBytes();
// 2.创建数据报,包含发送的数据信息
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
// 3.创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket();
// 4.向服务器端发送数据报
socket.send(packet);
/*
* 接收服务器端响应的数据
*/
// 1.创建数据报,用于接收服务器端响应的数据
byte[] data2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
// 2.接收服务器响应的数据
socket.receive(packet2);
// 3.读取数据
String reply = new String(data2, 0, packet2.getLength());
System.out.println("我是客户端,服务器说:" + reply);
// 4.关闭资源
socket.close();
}
}