网络编程:就是用来实现网络互联的不同计算机上运行的程序可以进行数据交流。(分布式系统涉及到了)
二、网络编程三要素:
1、IP:每台设备在网络中的唯一标识,每台网络始终在网络中有一个独立的地址,我们在网络中传输数据就是使用这个地址。
Ipconfig:查看本机IP
ping:测试连接
本地回路地址:127.0.0.1
2、端口号:每个网络程序都需要绑定一个端口号
传输数据的时候,除了确定发到哪台机器上,还要明确发到哪个程序。端口号的范围:0-65535
网络编程应用就需要绑定一个端口号,尽量使用1024以上。以下的基本被系统程序占用
常用端口号:
mysql:3306
oracle:1521
tomcat:8080
QQ:4000
端口号是为了标识这个程序的。
3、协议:
为计算机网络中进行数据交换而建立的规则,标准或约定的集合。
UDP:
面向无连接,数据不安全,速度快,不区分客户端与服务端
(给某个手机号发短信,不管你是否关机和是否为空号)
TCP:
面向连接(三次握手,四次挥手):数据安全,速度略低。分为客户端和服务端
三次握手:客户端先向发起请求,服务端响应请求,传输数据
(打电话:手机不能关机,不能是空号等)
三、Socket
Socket:套接字:学习网络编程,要围绕Socket进行学习。
1:进程标识:
一个主机的每一个网络进程使用协议、端口进行标识。要唯一确定网络环境的某个进程,就同时需要主机和端口号。(IP+端口号)
2、多重协议标识:
多重协议中需要指明是何种通信协议。
一个通信进程的多重协议标识需要一个三元组: {协议,本机IP,进程端口号}进行全局唯一地标识。
一个完整的网间进程通信由两个通信进程组成,需要一个五元组来标识:{协议、本机IP、本机进程端口、远程主机IP、远程主机进程端口}
2:通信的两端都有Socket。
3、网络通信其实就是Socket间的通信。
4、数据在两个Socket之间,通过IO流 进行传输。
5、Socket在应用程序中创建,通过一种 绑定机制与驱动程序。
四、Socket通信图解:
有两台主机,每台主机比作港口,Socket相当于港口的码头(一个港口可能又若干个码头)。两个港口之间通过船来传递货物,船就相当于IO流。
五、UDP传输
1、发送send
*创建DatagramSocket,随机端口号
*创建DatagramPacket,指定数据,长度,地址,端口
*使用DatagramSocket发送DatagramPacket
*关闭DatagramSocket
(DatagramSocket相当于码头,DatagramPacket相当于集装箱。)
public static void main(String[] args) throws SocketException,UnknowHostException{
String str = "红鲤鱼与绿鲤鱼与驴";//相当于货物
DatagramSocket socket = new DatagramSocket();//
DatagramPacket packet =new DatagramPacket(str.getBytes(),str.getBytes.length,InetAddress.getByName("127.0.0.1"),12345);
socket.send(packet)
socket.close();
}
2、接受Receive
*创建DatagramSocket,指定端口号
*创建DatagramePacket,指定数组,长度
*使用DatagramSocket接受DatagramPacket
*从DatagramPacket中获取数据
*关闭DatagramSocket
public static void main(String[] args) throws IOException{
DatagramSocket socket = new DatagramSocket(12345);
DatagramPacket packet =new DatagramPacket(new byte[1024],1024);
socket.receive(packet)
byte[] arr=packet.getData()//从集装箱获取数据
int len=packet.getLength();// 获取发过来的有效字节个数
system.out.println(new String(arr,0,len));
socket.close();
}
(发送和接受都是以字节流形式的。)
现在接收方和发送方已经准备就绪啦。我们可以使用dos窗口模拟一下数据的发送的过程。首先先启动接收方,然后再启动发送方。接下来,就能在接收方的dos窗口中看到:红鲤鱼与绿鲤鱼与驴啦。
六、TCP传输
TCP和UDP传输一样都是两台计算机进行通信,都需要创建Socket对象,区别在于UDP只需要发送端和接收端,不区分客户端和服务端。而TCP严格区分客户端和服务端。必须由客户端首先先去连接服务端才能实现通信。(服务端不能主动连客户端)
JDK的net包下Socket类表示客户端,ServerSocket表示服务端。首先创建一个ServerSocket对象,等待客户端连接。客户端创建一个Socket对象发送连接请求。
客户端的输出流对应服务端的输入流,服务端的输入流对应客户端的输出流。就相当于电话的麦克和听筒。
1、客户端
创建Socket连接服务端(指定Ip地址,端口号)通过IP地址找对应的服务器
调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
输入流可以读取服务端输出流写出的数据
输出端可以写出数据到服务端的输入流
public static void main(String[] args) throws UnknownHostException,IOException{
Socket socket = new Socket("127.0.0.1",9999);//创建一个客户端,socket
InputStream is = socket.getInputStream();//得到客户端的输入流
OutputStream os = socket.getOutputStream();//得到客户端的输出流
//发过来的是字节数组,用字节数组接收
byte[] arr = new byte[1024];
int len = is.read(arr);//读数据,写入
System.out.println(new String(arr,0,len));
os.write("学习挖掘机哪家强?",getBytes());//写数据,输出
byte[] arr2 = new byte[1024];
int len2 = is.read(arr2);//读数据,写入
System.out.println(new String(arr2,0,len2);
socket.close();//把这两个流也关了
}
2、服务端
创建ServerSocket(需要指定端口号)
调用ServerSocket的accept()方法接受一个客户端请求,得到一个Socket
调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
输入流可以读取客户端输出流写出的数据
输出流可以写出数据到客户端的输入流。
public static void main(String[] args) throws UnknownHostException,IOException{
ServerSocket server = new ServerSocket(9999);//创建一个服务器
Socket socket = server.accept();//接受客户端的请求,得到socket
InputStream is = socket.getInputStream();//得到服务端的输入流
OutputStream os = socket.getOutputStream();//得到服务端的输出流
os.write("百度一下你就知道".getBytes());// 写数据,输出
byte[] arr = new byte[1024];
int len = is.read(arr);//读数据,写入
System.out.println(new String(arr,0,len));
os.write("中国山东找蓝翔".getBytes());
server.close();//把服务器关了,可以不关
socket.close();
}
优化后的代码如下:
1、服务端
public static void main(String[] args) throws UnknownHostException,IOException{
ServerSocket server = new ServerSocket(9999);//创建一个服务器
Socket socket = server.accept();//接受客户端的请求,得到socket
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("欢迎来到王者荣耀"); //println是以/n/n来结束的
System.out.println(br.readLine());
ps.println("呵呵,你想多了");
System.out.println(br.readLine());
socket.close();
}
2、客户端
public static void main(String[] args) throws UnknownHostException,IOException{
Socket socket = new Socket("127.0.0.1",9999);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());
System.out.println(br.readLine());
ps.println("我要拿五杀"); //写给服务器
System.out.println(br.readLine());
ps.println("劳资要卸游戏");
socket.close();
}