java网络编程基础-传输层协议TCP&UDP

x33g5p2x  于2021-11-22 转载在 Java  
字(5.3k)|赞(0)|评价(0)|浏览(417)

一.网络编程基础

1.网络和网卡
网络是当前信息技术的第一推动力
每个计算机设备上都有若干个网卡
每个网卡上都有全球唯一的单独的硬件地址,MAC地址

2.IP地址:每个网卡/机器都有一个或多个IP地址

IPV4:192.168.0.100,每段0到255
IPV6:128bit长,分为8段,每段4个16进制数
本机保留IP:127.0.0.1
Windows通过ipconfig查询,Linux/Mac通过ifconfig

3.Port端口,0-65535

0-1023,OS以及占用了,80是Web,23是telent
1024-65535,一般程序可使用(谨防冲突)
两台机器通讯是在IP+Port上进行的
Windows/Linux/Mac通过netstat -an查询

4.公网(万维网/互联网)和内网(局域网)

网络是分层的
最外层是公网/互联网
底下的每层都是内网
IP地址可以在每个层次的网使用
tracert可看当前机器和目标机器的访问中继

5.传输层通讯协议

TCP(Transmission Control Protocol)
传输控制协议,面向连接的协议
两台机器的可靠无差错的数据传输
双向字节流传递
UDP(User Datagram Protocol)
用户数据报协议,面向无连接的协议
不保证可靠的数据传输
速度快,也可以在较差网络环境下使用

6.计算机通讯

数据从一个IP的port出发(发送方),运输到另一个IP的port(接收方)

二.UDP:无连接无状态的通讯协议

1.特性
发送方发消息,如果接收方刚好在目的地,则可以接收,如果不在,那这个消息就丢失了
发送方也无法得知是否发送成功
UDP的好处就是简单,节省,经济

2.思路

通过DatagramSocket建立通讯的数据管道ds
通过DatagramPacket建立数据的集装箱dp
向DatagramPacket中传入消息字节码和消息字节码长度
若为发送方,则传入地址标签:目的地IP+Port
通过InetAddress.getByName(“IP”)传入地址
send方法实现发送和receive方法实现接收
接收方必须早于发起方执行

3.demo:UdpRecv

  1. import java.net.DatagramPacket;
  2. import java.net.DatagramSocket;
  3. import java.net.InetAddress;
  4. public class UdpRecv {
  5. public static void main(String[] args) throws Exception
  6. {
  7. //定义管道为本机3000端口
  8. DatagramSocket ds=new DatagramSocket(3000);
  9. //定义字节数组存放信息
  10. byte [] buf=new byte[1024];
  11. //定义集装箱,用来封装信息
  12. DatagramPacket dp = new DatagramPacket(buf,1024);
  13. System.out.println("UdpRecv: 我在等待信息");
  14. //等待信息,如果有信息过来,则会封装在dp中
  15. //如果没有信息过来,则会造成阻塞
  16. ds.receive(dp);
  17. System.out.println("UdpRecv: 我接收到信息");
  18. //dp.getAddress().getHostAddress()方法获取IP
  19. //dp.getPort()方法获取Port
  20. String strRecv=new String(dp.getData()) +
  21. " from " + dp.getAddress().getHostAddress()+":"+dp.getPort();
  22. //打印信息和信息的来源地址
  23. System.out.println(strRecv);
  24. //线程暂停1s
  25. Thread.sleep(1000);
  26. //设置将要发送的信息
  27. String str="hello yh";
  28. //定义集装箱,装入dp内容和长度并且贴了目的地
  29. //目的地为127.0.0.1:3000
  30. //str.getBytes()方法把str类型转化为byte类型
  31. //str.length()
  32. //地址标签:目的地IP+Port
  33. DatagramPacket dp2=new DatagramPacket(str.getBytes(),str.length(),
  34. InetAddress.getByName("127.0.0.1"),dp.getPort());
  35. System.out.println("UdpRecv: 我要发送信息");
  36. //发送信息
  37. ds.send(dp2);
  38. System.out.println("UdpRecv: 我发送信息结束");
  39. //关闭管道
  40. ds.close();
  41. }
  42. }

4.demo:UdpSend

  1. import java.net.DatagramPacket;
  2. import java.net.DatagramSocket;
  3. import java.net.InetAddress;
  4. import java.nio.charset.StandardCharsets;
  5. public class UdpSend {
  6. public static void main(String [] args) throws Exception
  7. {
  8. //DatagramSocket:通讯的数据管道
  9. //定义管道
  10. DatagramSocket ds = new DatagramSocket();
  11. //定义将要发送的信息
  12. String str = "hello henrik";
  13. //定义集装箱,装入dp内容和长度并且贴了目的地
  14. //目的地为127.0.0.1:3000
  15. //str.getBytes()方法把str类型转化为byte类型
  16. //str.length()
  17. //地址标签:目的地IP+Port
  18. DatagramPacket dp = new DatagramPacket(str.getBytes(),str.length(),
  19. InetAddress.getByName("127.0.0.1"),3000);
  20. System.out.println("UdpSend: 我要发送信息");
  21. //发送信息
  22. ds.send(dp);
  23. System.out.println("UdpSend: 我发送信息结束");
  24. //进程暂停1s
  25. Thread.sleep(1000);
  26. //定义字节数组存放信息
  27. byte [] buf=new byte[1024];
  28. //定义集装箱用来封装信息
  29. DatagramPacket dp2 = new DatagramPacket(buf,1024);
  30. System.out.println("UdpSend: 我在等待信息");
  31. ds.receive(dp2);
  32. System.out.println("UdpSend: 我接收到信息");
  33. //dp.getAddress().getHostAddress()方法获取IP
  34. //dp.getPort()方法获取Port
  35. String str2 = new String(dp2.getData()) +
  36. " from " + dp2.getAddress().getHostAddress()+":"+dp2.getPort();
  37. //打印信息和信息的来源地址
  38. System.out.println(str2);
  39. //关闭管道
  40. ds.close();
  41. }
  42. }

5.效果

三.TCP:有连接,保证可靠的通讯协议

1.思路
服务器创建一个ServerSocket,等待连接
客户机创建一个Socket,连接到服务器
服务器的ServerSocket接收到连接,创建一个Socket和客户的Socket建立专线连接,后续服务器和客户机的对话(这一对Socket)会在一个单独的线程(服务端)上运行
服务端的ServerSocket继续等待连接

2.特性

服务端等待响应时,处于阻塞状态
服务端可以同时响应多个客户端
服务端每接受一个客户端,就启动一个独立的线程与之对应
客户端和服务端都可以选择关闭这对Socket的通道
ServerSocket作为服务器的码头,需要绑定port,如果有多块网卡,需要绑定一个ip地址
Socket作为运输通道,客户端往Socket输入流写入数据,送到服务端,从Socket输出流取服务器端过来的数据,服务端反之亦然

3.demo:TcpServer

  1. import java.net.*;
  2. import java.io.*;
  3. import java.nio.charset.StandardCharsets;
  4. public class TcpServer
  5. {
  6. public static void main(String [] args)
  7. {
  8. try{
  9. //驻守在8001端口
  10. ServerSocket ss = new ServerSocket(8001);
  11. //等待客户端连接
  12. Socket s = ss.accept();
  13. //阻塞提示
  14. System.out.println("welcome to the java world");
  15. //有人连接上打开输入流
  16. InputStream ips = s.getInputStream();
  17. //打开输出流
  18. OutputStream ops = s.getOutputStream();
  19. //同一个通道,服务端的输出流输入流就是客户端的输出流输入流
  20. //输出一句话给客户端
  21. ops.write("hello client".getBytes());
  22. //从客户端读取一句话
  23. BufferedReader br = new BufferedReader(new InputStreamReader(ips));
  24. System.out.println("client said:"+br.readLine());
  25. //关闭各对象
  26. ips.close();
  27. ops.close();
  28. s.close();
  29. ss.close();
  30. } catch (IOException exception) {
  31. exception.printStackTrace();
  32. }
  33. }
  34. }

4.demo:TcpClient

  1. import java.net.*;
  2. import java.io.*;
  3. public class TcpClient {
  4. public static void main(String[] args) {
  5. try {
  6. //用地址标签创建通道,这里需要服务端先开启
  7. Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8001);
  8. //同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流
  9. //开启通道的输入流
  10. InputStream ips = s.getInputStream();
  11. BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));
  12. //开启通道的输出流
  13. OutputStream ops = s.getOutputStream();
  14. //包装输出流
  15. DataOutputStream dos = new DataOutputStream(ops);
  16. //键盘录入信息
  17. //System.in是一个位流,InputStreamReader转换为字符流,然后再使用BufferedReader为其增加缓冲功能
  18. BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));
  19. while (true)
  20. {
  21. String strWord = brKey.readLine();
  22. //判断是否为换行,换行则表示结束
  23. if (strWord.equalsIgnoreCase("quit"))
  24. {
  25. break;
  26. }
  27. else
  28. {
  29. System.out.println("I want to send: " + strWord);
  30. //System.getProperty("line.separator")获取操作系统对应的换行符
  31. dos.writeBytes(strWord + System.getProperty("line.separator"));
  32. System.out.println("Server said: " + brNet.readLine());
  33. }
  34. }
  35. //关闭对象
  36. dos.close();
  37. brNet.close();
  38. brKey.close();
  39. s.close();
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }

5.效果

相关文章

最新文章

更多