个人重点总结:
TCP协议:传输控制协议
- 使用TCP协议之前,须先建立TCP连接,形成传输数据通道
- 传输前,采用三次握手的方式是可靠的
- TCP协议进行通信的两个应用进程:客户端,服务端
- 在连接中可以进行大数据量的传输
- 传输完毕,需要释放已建立的连接,效率低
UDP协议:用户数据协议
- 将数据,源,目的封装成数据包,不需要建立连接
- 每个数据包的大小限制在64k内
- 因无需连接,故是不可靠的
- 发送数据结束无需释放资源(因为不是面向连接的),速度快
- 举例:发短信
Socket
基本介绍:
- 通信的两端都要有Socket,是两台机器间通信的端点
- 网络通信其实就是Socket间的通信
- Socket允许程序把网络连接当成一个流,数据在两个socket之间通过io传输
- 一般主动发起通信的的应用程序属于客户端,等待通信请求的为服务端
TCP网络通信编程
- 基于客户端-服务端的网络通信
- 底层使用的是TCP/IP协议
- 应用场景:客户端发送数据,服务端接收并显示
- 基于Socket的TCP编程
实例:
客户端:
public class Client {
public static void main(String[] args) throws IOException {
//1.连接服务端(ip,端口)
//连接本机的9999端口 ,如果连接成功,返回socket对象
Socket socket = new Socket(InetAddress.getLocalHost(),6666);
BufferedInputStream buf = new BufferedInputStream(new FileInputStream("E:\\1\\1.png"));
//字节流转数组
byte[] bytes = StreamUtils.InputStreamTOByte(buf);
//通过socket获取输出流, 将字节数组输出到服务端
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
bufferedOutputStream.write(bytes); //写入数据通道
socket.shutdownOutput();
String s = StreamUtils.InputStreamTOString(socket.getInputStream());
System.out.println(s);
bufferedOutputStream.close();
bufferedOutputStream.close();
socket.close();
}
}
服务端:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(6666);
Socket accept = serverSocket.accept();
//获取客户端发送的数据
//得到输入流
BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
//字节流转数组
byte[] bytes = StreamUtils.InputStreamTOByte(bis);
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("E:\\1\\a.png"));
bos.write(bytes);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bufferedWriter.write("收到图片");
bufferedWriter.flush();
accept.shutdownOutput();
bufferedWriter.close();
bos.close();
bis.close();
accept.close();
serverSocket.close();
}
}
UDP网络通信编程
基本介绍:
- 类DatagramSocket和DatagramPacket(数据报/数据包)实现了基于UDP协议网络程序
- UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能安全送到目的地,也不能确定什么时候可以抵达
- DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的ip地址和端口号,数据
- UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
UDP网络编程示意图
基本流程
- 核心的两个类DatagramSocket和DatagramPacket
- 建立发送端和接收端(没有服务端和客户端概念)
- 发送数据前,建立数据报/数据包(DatagramPacket)对象
- 调用DatagramSocket的发送,接收方法
- 关闭DatagramSocket
实例:
发送端
public class UDPSenderB {
public static void main(String[] args) throws IOException {
//1.创建一个DatagramSocket对象,准备在9999端口接收数据
DatagramSocket socket = new DatagramSocket(9998);
//2.将需要的课程封装到DatagramPacket data内容字节数组,data.length,ip地址,端口
byte[] data = "你好啊,明天吃饭".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data,data.length, InetAddress.getByName("192.168.1.6"),9999);
InetAddress byName = InetAddress.getByName("192.168.1.3");
System.out.println(byName);
socket.send(datagramPacket);
socket.close();
System.out.println("发送完成");
}
}
接收端
public class UDPReceiverA {
public static void main(String[] args) throws IOException {
//1.创建一个DatagramSocket对象,准备在9999端口接收数据
DatagramSocket socket = new DatagramSocket(9999);
//2.构建一个DatagramPacket对象,准备接收数据 数据包最大为64kb
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
//3.调用接收方法,将通过网络传输的DatagramPacket对象填充到packet对象
//注意:当数据包发送到本机的9999端口时,就会接收数据,当没有数据发送到9999端口时,就会阻塞
System.out.println("接收端A等待接收数据");
socket.receive(packet);
//4.把packet进行拆包,取出数据,并显示
int length = packet.getLength();//接收的数据长度
byte[] data = packet.getData();//接收的数据
String s = new String(data, 0, length);
System.out.println(s);
System.out.println("接收端A接收数据完成");
}
}
总结:
发送端,发送的客户端ip有错误,他也会发送完成,不知道接收方是否接收成功发送端就会退出,而接收端因为没接收到数据一直会阻塞,不会退出
QQ登录实战
最后实战链接放到了gitee上,离线消息也已经实现
网络: 控制台实现了qq的私聊,群发,发送文件,消息推送,退出登录功能
https://gitee.com/liang0608/network