网络概述
协议
在网络之间传出数据时需要按照指定的标准来传输,标准中规定了数据的格式、大小、传输的方式、传输速率。形成统一规范—>按照规范开发的代码—>协议(应用层、传输层、网络层、链路层)
InetAddress类
用来分装网络地址:IP地址、端口、主机名称
UDP协议编程
UDP(User Datagram protocol),用户数据报协议;
特点:
发送端只发送数据,不管接收端是否接收数据或者接收数据是否完整接受端只管接受数据允许发送的数据出现丢失的现象
电视直播、广播
TCP 传输控制协议
特点:
1. 客户端:发送数据
2. 服务器:接受数据
3. 不允许出现数据丢失的情况
长传下载文件
TCP/IP的三次握手:第一次握手,客户端向服务器端发出连接请求,等待服务器确认,第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求,第三次握手,客户端再次向服务器端发送确认信息,确认连接。
UDP通信的过程
DatagramSocket类(码头 用来存放数据包(集装箱)DatagramPacket)DatagramPacket类(集装箱 用来装载数据)UDP接收端的过程
简单原理:创建一个能接收(存放)数据报(集装箱)的数据平台(码头)。
创建DatagramSocket(码头)来存放数据报(集装箱),这个码头要有编号(port 端口号),用来接收具有相同端口号的数据报。创建有一定规格的DatagramPacket(集装箱)不需要知道是那里来的数据报。接受数据报读取数据报里的数据关闭码头
代码
import .DatagramPacket;import .DatagramSocket;import .InetAddress;public class Receive {public static void main(String[] args)throws Exception {//创建能存放数据报(DatagramPacket) 的 DatagramSocket(码头) 对象需指定端口号DatagramSocket s=new DatagramSocket(6000);//创建一个有大小的数据报对象 相当于集装箱 用来接收数据byte []buf=new byte[1024];DatagramPacket dp=new DatagramPacket(buf,1024);//让码头接收数据报(集装箱)s.receive(dp);//读取集装箱里的数据byte[] data = dp.getData();String dataStr=new String(data);InetAddress address = dp.getAddress();String hostName = address.getHostName();System.out.println(hostName);System.out.println(dataStr);//关闭码头 不在接收数据报(集装箱)}}
UDP发送端过程
简单原理:创建一个能发送数据报(集装箱)的数据平台(码头)。
创建能存放数据报(DatagramPacket) 的 DatagramSocket(码头) 无需指定端口号创建数据报(集装箱)上要有目的地的信息、端口号等。发送数据报
关闭码头
import .DatagramPacket;import .DatagramSocket;import .InetAddress;public class Send {public static void main(String[] args) throws Exception{//创建能存放数据报(DatagramPacket) 的 DatagramSocket(码头)无需指定端口号DatagramSocket s=new DatagramSocket();//创建数据报(集装箱)用来装载数据 需要指明目的地//byte []b=new byte[1024];byte []b="今晚七点我们在操场见面".getBytes();DatagramPacket dp=new DatagramPacket(b, b.length, InetAddress.getByName("192.168.88.1"), 6000);//发送数据报s.send(dp);//关闭码头s.close();}}
TCP通信的过程
需要注意的是:TCP通信不同于UDP通信,TCP通信需要先通过客户端连接服务器端才能实现通信,服务器不能直接连接客户端,服务器必须要先启动,等待客户端的连接。
客户端:Socket服务器端:ServerSocket先创建服务器端在创建客户端
TCP服务器端响应过程
创建服务器端,使用ServerSocket类,需要设置服务器的端口号开启客户端连接,返回一个客户端对象获得客户端发过来的信息,并输出到控制台上(输入流)响应客户端的请求,给客户端发送信息(输出流)关闭流和客户对象
import java.io.InputStream;import java.io.OutputStream;import .ServerSocket;import .Socket;public class Server {public static void main(String[] args) throws Exception{//创建服务器端 使用ServerSocket 需要指定服务器的端口号ServerSocket s=new ServerSocket(6000);//开启客户端连接 返回客户端对象Socket socket = s.accept();//获得客户端发过来的信息 (客户端--->写入到服务器)InputStream in = socket.getInputStream();//控制台打印客户端发送过来的信息int len=-1;byte []b=new byte[1024];while((len=in.read(b))!=-1){System.out.println(new String(b,0,len));}//服务器响应客户端的请求OutputStream out = socket.getOutputStream();out.write("服务器收到".getBytes());//关闭流in.close();out.close();//关闭客户端socket.close();//服务器一般不关s.close();}
}
TCP客户端请求服务器端过程
创建客户端对象 指定要连接的服务器的地址和端口号获得输出流对象,将要发送的数据写到服务器端客户端发送数据结束标识,告诉服务器数据发送完毕接受服务器响应的数据关闭流关闭客户端对象
import java.io.InputStream;import java.io.OutputStream;import .Socket;public class Client {public static void main(String[] args)throws Exception {//创建客户端对象并初始化要连接的服务器端的地址和端口Socket s=new Socket("192.168.88.1",6000);//获得输出流,将数据发送给服务器OutputStream out = s.getOutputStream();out.write("嗨,我是客户端 ".getBytes());//给服务器标识 客户端已经完成了数据的发送s.shutdownOutput();//接受服务器返回来的信息InputStream in = s.getInputStream();int len=-1;byte[] b=new byte[1024];while((len=in.read(b))!=-1){System.out.println(new String(b,0,len));}//关闭流out.close();in.close();//关闭客户端s.close();}}
多线程文件上传练习
服务器端
import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .ServerSocket;import .Socket;/*** 多线程实现文件上传* * @author YandeHu**/public class Server {public static void main(String[] args) throws Exception {// 创建服务器端 ServerSocket类 设置端口号ServerSocket s = new ServerSocket(6000);while (true) {// 创建客户对象 开启客户端连接final Socket socket = s.accept();// 创建线程匿名内部类new Thread() {@Overridepublic void run() {try {// 客户端获取输入流对象将客户端的消息显示出来InputStream in = socket.getInputStream();// 创建文件输出流FileOutputStream fos = new FileOutputStream(System.currentTimeMillis() + ".jpg");int len = -1;byte[] b = new byte[1024];while ((len = in.read(b)) != -1) {fos.write(b);}// 响应客户端OutputStream out = socket.getOutputStream();out.write("文件上传成功".getBytes());// 关闭流in.close();fos.close();out.close();// 关闭客户端socket.close();} catch (IOException e) {e.printStackTrace();}}}.start();}}}
客户端
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import .Socket;public class Client {public static void main(String[] args)throws Exception {//创建客户端类Socket s=new Socket("192.168.88.1",6000);//创建文件输入流FileInputStream fis=new FileInputStream("E:\\微信、ps素材\\微信素材文件\\图片素材\\爱情.jpg");//获取输出流OutputStream out = s.getOutputStream();int len=-1;byte[]b=new byte[1024];while((len=fis.read(b))!=-1){out.write(b,0,len);}//设置标记 标记上传文件结束s.shutdownOutput();//获得服务器响应的信息InputStream in = s.getInputStream();int len1=-1;byte[]n=new byte[1024];while((len1=in.read(n))!=-1){System.out.println(new String(n,0,len1));}//关闭流fis.close();out.close();in.close();//关闭客户端s.close();}}