先唠叨一些基础东西:
1、两台计算机间进行通讯需要以下三个条件:
IP地址、协议、端口号
2、IP地址、端口
为实现网络中不同计算机之间的通信,每台计算机都必须有一个唯一的标识—IP地址。而区分一台主机的多个不同应用程序,则是用端口标识,端口号范围为0-65535,其中0-1023位为系统保留。IP地址+端口号组成了所谓的Socket。
3、Socket套接字:
网络上具有唯一标识的IP地址和端口组合在一起才能构成唯一能识别的标识符套接字。
Socket的原理机制:通信的两端都有Socket,网络通信其实就是Socket间的通信,而数据在两个Socket间通过IO传输
4、Java中的网络支持
针对网络通信的不同层次,Java提供了不同的API,其提供的网络功能有四大类:
InetAddress:用于标识网络上的硬件资源,主要是IP地址
URL:统一资源定位符,通过URL可以直接读取或写入网络上的数据
Sockets:使用TCP协议实现的网络通信Socket相关的类
Datagram:使用UDP协议,将数据保存在用户数据报中,通过网络进行通信。
接下来一步步和大家分享的我的小代码来帮助大家轻松愉快弄懂这东西:
demo:利用socket实现客户端获取服务器当前的时间、日期和指定目录下的文件列表(UDP)
首先第一个问题,怎么在一个Java程序中假装出一个客户端和一个服务器?很容易想到把他们丢在两个线程上运行,这样就好像两方在一唱一和互相进行通信。话不多说,建两个class:client和serve,继承Thread类,重写它的构造函数和run方法。
client头文件:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
server头文件:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
两线程大致框架:
public class XXX extends Thread{
public ClientThread(String threadName){
super(threadName);
}
public void run(){
balabala
}
}
当然还需要一个来跑着两个线程的东西,于是我们再新建class取个名MultiThread,具体内容:
public class TestMultiThread{
public static void main(String[] args){
new ServerThread("server").start();
new Client("client").start();
}
}
接下来考虑两个线程run里的内容,也是本文核心部分。
第一步,我们应该从server入手,先要有一个服务器出现在那里,你才有目标访问。所以server里率先进行一波操作:
Serve:
1.创建服务器端DatagramSocket,指定端口
DatagramSocket socket;
socket = new DatagramSocket(8800);
2.创建数据报,用于接收客户端发送的数据
byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
DatagramPacket packet = new DatagramPacket(data, data.length);
3.接收客户端发送的数据
System.out.println("服务器:服务器端已经启动,等待客户端发送数据");
socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
第二步,现在服务器处于阻塞状态,也就是正在等待客户端一个数据报来使它运作起来,所以这里我们转移阵地到client里向server发送一个请求连接的socket:
Client:
1.定义服务器的地址、端口号、数据
InetAddress address;
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);
第三步,回到服务器端,要做的就是拿到刚刚receive会得到的数据报并反馈给客户端信息
Serve:
1.读取数据
String info = new String(data, 0, packet.getLength());
System.out.println("服务器:客户端说:" + info);
2.定义客户端的地址、端口号、数据
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data2 = "欢迎您!".getBytes();
3.创建数据报,包含响应的数据信息
DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
4.响应客户端
socket.send(packet2);
5.等待客户端下一次请求
System.out.println("服务器:等待客户端发送请求");
socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
第四步,客户端收到响应回来的信息再进行处理,完成一次交互
Client:
String reply = new String(data, 0, packet.getLength());
System.out.println("客户端:服务器说:" + reply);
上边我们试验了一下UDP传递数据报在服务器和客户端分别是怎么操作的了,那么接下来还是先来用这种最简单的方法把日期时间和指定目录的路径的操作按照上面的操作来一遍:
Client的run:
try {
InetAddress address