1.5 通信协议
协议:约定
网络通信协议:速率,传输码率,代码结构,传输控制...
问题:非常复杂
大事化小:分层!
TCP/IP协议簇:实际上是一组协议
重要:
-
TCP:用户传输协议
-
UDP:用户数据报协议
出名的协议:
-
TCP:
-
IP:网络互连协议
TCP,UDP对比
TCP:打电话
-
连接,稳定
-
三次握手,四次挥手
最少需要三次,保证稳定连接
A:你瞅啥
B:瞅你咋地
A:干一场
A:我要断开了
B:我知道你要断开了
B:你真的真的断开了吗
A:我真的要断开了 -
客户端,服务端:主动跟被动
-
传输完成,释放连接,效率低
UDP:发短信
-
不连接,不稳定
-
客户端,服务端:没有明确的界限
-
不管有没有准备好,都可以发给你
-
导弹攻击
-
DDOS:洪水攻击!饱和攻击
1.6 TCP
客户端
-
连接服务器Socket
-
发送消息
package com.yuan.lesson02; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; //客户端 public class TcpClientDemo01 { public static void main(String[] args) { Socket socket =null; OutputStream os =null; try { //1. 要知道服务器的地址, 端口号 InetAddress serverIP = InetAddress.getByName("127.0.0.1"); int port =9999; //2. 创建一个socket连接 socket = new Socket(serverIP,port); //3. 发送消息 IO流 os = socket.getOutputStream(); os.write("你好,欢迎学习java".getBytes()); } catch (Exception e) { e.printStackTrace(); }finally { if (os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket!=null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
服务器
-
建立服务的端口ServerSocket
-
等待用户连接accept
-
接收用户的消息
package com.yuan.lesson02; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; //服务端 public class TcpServerDemo01 { public static void main(String[] args) { ServerSocket serverSocket=null; Socket socket=null; InputStream is =null; ByteArrayOutputStream baos =null; try { //1. 我得有一个地址 serverSocket = new ServerSocket(9999); //2. 等待客户端连接过来 socket = serverSocket.accept(); //3. 读取客户端的消息 is = socket.getInputStream(); //用字节流字节数组读消息有中文会断,可以用管道流 baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len= is.read(buffer))!=-1){ baos.write(buffer,0,len); } System.out.println(baos.toString()); } catch (IOException e) { e.printStackTrace(); }finally { //关闭资源 if(baos!=null){ try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } if (is!=null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket!=null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } if (serverSocket!=null) { try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
文件上传
先开服务端,一直在监听连接,再开客户端
成功上传会出现一个server.png文件
增加接收完毕的提示
但运行的时候什么都没有
两边都没结束
服务器端一直在等待用户输入,然后告诉他我接收完了
客户端有问题,客户端什么时候真正写完没有告诉服务器,一写完又马上等待服务器端的输入了
所以在客户端加一块通知服务器我已经结束了
这句话是由服务器发送,客户端接收
服务器端
package com.yuan.lesson02; import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class TcpServerDemo02 { public static void main(String[] args) throws IOException { //1. 创建服务端口 ServerSocket serverSocket = new ServerSocket(9000); //2. 监听客户端的连接 Socket socket=serverSocket.accept();//阻塞式监听,会一直等待客户端连接 //3. 获取输入流 InputStream is = socket.getInputStream(); //4. 文件输出 FileOutputStream fos = new FileOutputStream(new File("receive.png")); byte[] buffer = new byte[1024]; int len; while ((len=is.read(buffer))!=-1){ fos.write(buffer,0,len); } //通知客户端我接收完毕了 OutputStream os = socket.getOutputStream(); os.write("我接收完毕了,你可以断开了".getBytes()); //关闭资源 fos.close(); is.close(); socket.close(); serverSocket.close(); } }
客户端
package com.yuan.lesson02; import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class TcpClientDemo02 { public static void main(String[] args) throws IOException { //1. 创建一个Socket连接 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000); //2. 创建一个输出流 OutputStream os = socket.getOutputStream(); //3. 读取文件 FileInputStream fis = new FileInputStream(new File("shadow_icon.png")); //4. 写出文件 byte[] buffer = new byte[1024]; int len; while ((len=fis.read(buffer))!=-1){ os.write(buffer,0,len); } //通知服务器,我已经结束了 socket.shutdownOutput();//我已经传输完了! //确定服务器接收完毕,才能够断开连接 InputStream inputStream = socket.getInputStream(); //通过管道流转化 ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer2 = new byte[1024]; int len2; while ((len2=inputStream.read(buffer2))!=-1){ baos.write(buffer2,0,len2); } System.out.println(baos.toString()); //5. 关闭资源 baos.close(); inputStream.close(); fis.close(); os.close(); socket.close(); } }
来源:b站狂神