什么是网络编程?

基于网络通信协议的编程,这类编程是以网络通信协议为基础的。

网络通信的要素:

通信双方的地址:
1、ip , 端口号
2、网络通信协议 TCP,UDP

IP:

唯一确定网络上的一台计算机
本机:127.0.0.1 或 loalhost

端口号:

所谓的端口,就好像是门牌号一样,客户端可以通过ip地址找到对应的服务器端,但是服务器端是有很多端口的,每个应用程序对应一个端口号,通过类似门牌号的端口号,客户端才能真正的访问到该服务器。为了对端口进行区分,将每个端口进行了编号,这就是端口号。
一个IP地址的端口通过16bit进行编号,最多可以有65536个端口。
其中,0~1023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败。

获取IP:InetAddress

  1. package com.smiledog.wangluobiancheng.socket;
  2. /*
  3. @ClassName UDPDemo
  4. @Author SmILeDog
  5. @Date 2021/5/11
  6. @Time 13:39
  7. */
  8. import java.net.InetAddress;
  9. import java.net.UnknownHostException;
  10. public class InetAddressDemo {
  11. public static void main(String[] args) throws UnknownHostException {
  12. // CSDN:InetAddress类没有构造方法,所以不能直接new出一个对象;
  13. // 可以通过InetAddress类的静态方法获得InetAddress的对象;
  14. InetAddress localHost = InetAddress.getLocalHost();
  15. System.out.println(localHost);//DESKTOP-IDATELU/172.16.16.107 主机名/ip地址
  16. InetAddress address = InetAddress.getLocalHost();
  17. System.out.println("计算机名:" + address.getHostName());
  18. System.out.println("IP地址:" + address.getHostAddress());
  19. }
  20. }
  21. 运行结果:
  22. DESKTOP-IDATELU/172.16.16.107
  23. 计算机名:DESKTOP-IDATELU
  24. IP地址:172.16.16.107

TCP和UDP:

TCP:用户传输协议 (三次握手,四次挥手)
比如:打电话 ===》需要建立连接
需要连接,较稳定
客户端,服务端
传输完成,释放连接,效率低

  1. - 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
  2. - 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
  3. - 第三次握手,客户端再次向服务器端发送确认信息,确认连接。
  4. 三次握手:
  5. 客户端:你好服务器,我要和你建立连接
  6. 服务器:好的客户端,已经答应和你建立连接并通知了服务器应用程序(单向连接建立)
  7. 客户端:好的服务器,已经通知应用程序进行连接(双向连接建立)
  8. 四次挥手:
  9. 客户端:你好服务器,我要和你断开连接
  10. 服务器:好的客户端,已经通知服务器应用程序
  11. 服务器:服务器应用程序通知我可以断开连接了(服务器断开连接)
  12. 客户端:好的服务器,已经通知应用程序断开了(客户端断开连接)

UDP:用户数据报协议
比如:发短信 ===》不需要建立连接
不需要连接,不稳定
客户端,服务端 两者没有明确的界限
不管你准没准备好接收,反正我是发给你了

TCP案例:文件的上传

  1. package com.smiledog.wangluobiancheng.socket.TCPDemo.test2;
  2. /*
  3. @ClassName Client
  4. @Author SmILeDog
  5. @Date 2021/5/11
  6. @Time 17:02
  7. 模拟客户端 进行 上传文件
  8. */
  9. import java.io.*;
  10. import java.net.InetAddress;
  11. import java.net.Socket;
  12. public class Client {
  13. public static void main(String[] args) throws IOException {
  14. //创建客户端 指定目标ip和端口
  15. Socket socket = new Socket(InetAddress.getLocalHost(),12345);
  16. //通过socket获取输出流
  17. OutputStream os = socket.getOutputStream();
  18. //读取文件,传给服务器
  19. FileInputStream fis = new FileInputStream(new File("day15\\1.jpg")); //读取指定文件
  20. byte[] bys = new byte[1024];
  21. int line;
  22. while ((line = fis.read(bys)) != -1){
  23. os.write(bys,0,line);
  24. }
  25. socket.shutdownOutput(); //调用停止输出流,用于停止阻塞,让程序走完
  26. InputStream is = socket.getInputStream(); //获取输入流,读取服务器返回信息!
  27. int read = is.read(bys);
  28. System.out.println(new String(bys,0,read));
  29. //关闭资源
  30. os.close();
  31. fis.close();
  32. }
  33. }
  34. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. package com.smiledog.wangluobiancheng.socket.TCPDemo.test2;
  36. /*
  37. @ClassName Server
  38. @Author SmILeDog
  39. @Date 2021/5/11
  40. @Time 17:02
  41. 模拟服务器 进行 接收文件
  42. ps: 添加多线程,用于多个用户上传文件的需求
  43. ps:应该添加一个判断,获取文件类型,然后确定传进来的是什么文件,把jpg变成可变的。
  44. */
  45. import java.io.*;
  46. import java.net.ServerSocket;
  47. import java.net.Socket;
  48. import java.util.Random;
  49. public class Server {
  50. public static void main(String[] args) throws IOException {
  51. //创建服务器 指定IP
  52. ServerSocket serverSocket = new ServerSocket(12345);
  53. System.out.println("服务器已打开,等待上传。。。");
  54. while (true) {
  55. Socket socket = serverSocket.accept(); //创建服务器监听
  56. new Thread(new ServerThread(socket)).start(); //传入客户端 开启线程
  57. }
  58. }
  59. }
  60. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61. package com.smiledog.wangluobiancheng.socket.TCPDemo.test2;
  62. /*
  63. @ClassName ServerThread
  64. @Author SmILeDog
  65. @Date 2021/5/11
  66. @Time 17:56
  67. */
  68. import java.io.*;
  69. import java.net.ServerSocket;
  70. import java.net.Socket;
  71. import java.util.Random;
  72. public class ServerThread implements Runnable{
  73. private Socket socket;
  74. public ServerThread(Socket socket) {
  75. this.socket = socket;
  76. }
  77. @Override
  78. public void run() {
  79. try {
  80. InputStream is = socket.getInputStream();//通过客户端获取输入流
  81. //创建个字符串用于接收的文件命名问题,避免名称重复问题 客户端的主机名+当前时间+8位的随机整数
  82. String fileName = socket.getInetAddress().getHostName() + System.currentTimeMillis() + new Random().nextInt(99999999);
  83. //创建文件输出流,进行写数据
  84. FileOutputStream fos = new FileOutputStream(new File("day15\\" + fileName + ".jpg")); //创建字节输出流
  85. //读取数据内容
  86. byte[] bys = new byte[1024];
  87. int line;
  88. while ((line = is.read(bys)) != -1) { //读取客户端传入的数据
  89. fos.write(bys, 0, line); //读取的数据写入服务器
  90. }
  91. OutputStream os = socket.getOutputStream(); //获取输出流,写入返回客户端信息!
  92. os.write("上传成功!".getBytes());
  93. System.out.println("来自:"+socket.getInetAddress().getHostAddress()+"上传文件成功!");
  94. //关闭资源
  95. fos.close();
  96. is.close();
  97. os.close();
  98. } catch (IOException e) {
  99. e.printStackTrace();
  100. }
  101. }
  102. }

UDP案例:公共聊天室

  1. package com.smiledog.wangluobiancheng.socket.UDPDemo.chijiuhua;
  2. /*
  3. @ClassName SendDemo
  4. @Author SmILeDog
  5. @Date 2021/5/11
  6. @Time 14:48
  7. 模拟客户端
  8. */
  9. import java.io.IOException;
  10. import java.net.DatagramPacket;
  11. import java.net.DatagramSocket;
  12. import java.net.InetAddress;
  13. import java.util.Scanner;
  14. public class SendDemo {
  15. public static void main(String[] args) throws IOException {
  16. //创建客户端
  17. DatagramSocket socket = new DatagramSocket();
  18. Scanner sc = new Scanner(System.in);
  19. while (true){ //一直输出数据 直到输入bye,不区分大小写
  20. System.out.println("请输入:");
  21. String s = sc.nextLine();
  22. if (s.equalsIgnoreCase("bye")){
  23. socket.close(); //客户端输入bye,关闭资源
  24. }
  25. byte[] bys = s.getBytes(); //将字符串转成数组
  26. //将数据打包 : DatagramPacket(数组,长度,目标ip地址,目标端口)
  27. DatagramPacket packet = new DatagramPacket(bys, bys.length,InetAddress.getLocalHost() , 12306);
  28. socket.send(packet); //发送包
  29. //socket.close(); //关闭资源
  30. }
  31. }
  32. }
  33. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  34. package com.smiledog.wangluobiancheng.socket.UDPDemo.chijiuhua;
  35. /*
  36. @ClassName ReceiveDemo
  37. @Author SmILeDog
  38. @Date 2021/5/11
  39. @Time 15:43
  40. 模拟服务器
  41. */
  42. import java.io.IOException;
  43. import java.net.DatagramPacket;
  44. import java.net.DatagramSocket;
  45. public class ReceiveDemo {
  46. public static void main(String[] args) throws IOException {
  47. //定义一个接收端,并指定端口号
  48. DatagramSocket socket = new DatagramSocket(12306);
  49. while (true) {
  50. //接受客户端传过来的数据包
  51. byte[] bys = new byte[1024]; //定义数组接收数据包
  52. // 解析数据包 ,客户端传过来的数据都在这个packet里边了
  53. DatagramPacket packet = new DatagramPacket(bys, bys.length);
  54. socket.receive(packet); //接收数据包内容
  55. String ip = packet.getAddress().getHostAddress(); //获取前端传过来的包中的ip地址
  56. bys = packet.getData(); //获取包中的数据内容
  57. int datalength = packet.getLength(); //获取文件内容的大小,如果直接打印bys的大小,打印的是初始化那个大小的值
  58. System.out.println("packet.getData().length:"+datalength);
  59. String data = new String(bys, 0, datalength);
  60. System.out.println("来自:" + ip + "内容为:" + data);
  61. }
  62. }
  63. }

URL:下载网络资源

  1. package com.smiledog.wangluobiancheng;
  2. /*
  3. @ClassName URlDemo
  4. @Author SmILeDog
  5. @Date 2021/5/11
  6. @Time 20:11
  7. */
  8. import java.io.FileOutputStream;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.net.HttpURLConnection;
  12. import java.net.URL;
  13. import java.text.SimpleDateFormat;
  14. import java.util.Date;
  15. public class URlDemo {
  16. public static void main(String[] args) throws IOException {
  17. //下载地址
  18. URL url = new URL("https://m701.music.126.net/20210511205517/3f7bba4fb2bc0c1c9703573ea695fbf9/jdyyaac/525b/0f5d/060c/e1c731b12687d4fe07cc1fac64103777.m4a");//括号里是网络资源的网址
  19. String file = url.getPath(); //获取文件路径
  20. int i = file.lastIndexOf("."); //返回指定字符最后一次出现的位置
  21. String sub = file.substring(i);
  22. //连接到资源
  23. HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
  24. //调用字节输入流
  25. InputStream is = urlConnection.getInputStream();
  26. //创建文件输出流
  27. //避免名称重复
  28. SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss"); //格式化样式
  29. String format = sdf.format(new Date()); //格式化
  30. String fileName= format;
  31. FileOutputStream fos = new FileOutputStream("E:\\music\\"+fileName+sub);
  32. byte[] bys = new byte[1024];
  33. int len;
  34. while ((len = is.read(bys))!=-1){ //读取资源
  35. fos.write(bys,0,len); //把资源写入本地
  36. }
  37. //关闭资源
  38. fos.close();
  39. is.close();
  40. urlConnection.disconnect();
  41. }
  42. }

控制台公共聊天室:

  1. package com.yunhe.socket;
  2. /*
  3. @ClassName Client
  4. @Author SmILeDog
  5. @Date 2021/6/8
  6. @Time 16:33
  7. 模拟客户端
  8. */
  9. import java.io.*;
  10. import java.net.Socket;
  11. import java.util.Scanner;
  12. public class Client {
  13. public static void main(String[] args) {
  14. Scanner sc = new Scanner(System.in);
  15. // String ip = "172.16.16.100";
  16. String ip = "127.0.0.1";
  17. int port = 12306;
  18. String line = null;
  19. Socket socket = null;
  20. InputStream is = null;
  21. OutputStream os = null;
  22. BufferedReader br = null;
  23. BufferedWriter bw = null;
  24. try {
  25. while (true){
  26. //监听端口
  27. socket = new Socket(ip,port);
  28. //获取字节输入流
  29. is = socket.getInputStream();
  30. //获取字节输出流
  31. os = socket.getOutputStream();
  32. //获取字符缓冲输入流
  33. br = new BufferedReader(new InputStreamReader(is));
  34. //获取字符缓冲输出流
  35. bw = new BufferedWriter(new OutputStreamWriter(os));
  36. //客户端发送数据
  37. System.out.println("请输入需要发送给服务器的内容:");
  38. String str = sc.nextLine();
  39. bw.write(str);//发送数据
  40. bw.flush(); //刷新流
  41. socket.shutdownOutput();
  42. //接受服务器端的相应数据
  43. while ((line = br.readLine()) !=null){
  44. System.out.println("收到服务器端的响应内容:"+line); //打印相应内容
  45. }
  46. socket.shutdownInput();
  47. }
  48. } catch (IOException e) {
  49. e.printStackTrace();
  50. }finally {
  51. if (bw!=null){
  52. try {
  53. bw.close();
  54. } catch (IOException e) {
  55. e.printStackTrace();
  56. }
  57. }
  58. if (br!=null){
  59. try {
  60. br.close();
  61. } catch (IOException e) {
  62. e.printStackTrace();
  63. }
  64. }
  65. if (os!=null){
  66. try {
  67. os.close();
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. }
  72. if (is!=null){
  73. try {
  74. is.close();
  75. } catch (IOException e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. if (socket!=null){
  80. try {
  81. socket.close();
  82. } catch (IOException e) {
  83. e.printStackTrace();
  84. }
  85. }
  86. }
  87. }
  88. }
  1. package com.yunhe.socket;
  2. /*
  3. @ClassName server
  4. @Author SmILeDog
  5. @Date 2021/6/8
  6. @Time 16:54
  7. 模拟服务器端
  8. */
  9. import java.io.*;
  10. import java.net.ServerSocket;
  11. import java.net.Socket;
  12. import java.util.Scanner;
  13. public class server {
  14. public static void main(String[] args) throws IOException {
  15. Scanner sc = new Scanner(System.in);
  16. int port = 12306;
  17. String line = null;
  18. String str = null;
  19. Socket socket = null;
  20. ServerSocket serverSocket = null;
  21. InputStream is = null;
  22. OutputStream os = null;
  23. BufferedReader br = null;
  24. BufferedWriter bw = null;
  25. serverSocket = new ServerSocket(port);
  26. try {
  27. while (true) {
  28. System.out.println("======服务器端正在接收数据======");
  29. socket = serverSocket.accept();
  30. //获取字节输入流
  31. is = socket.getInputStream();
  32. //获取字节输出流
  33. os = socket.getOutputStream();
  34. //获取字符缓冲输入流
  35. br = new BufferedReader(new InputStreamReader(is));
  36. //获取字符缓冲输出流
  37. bw = new BufferedWriter(new OutputStreamWriter(os));
  38. //接受服务器端的相应数据
  39. while ((line = br.readLine()) != null) {
  40. System.out.println("收到客户端"+socket.getInetAddress().getHostAddress()+"发来的消息:" + line); //打印相应内容
  41. }
  42. socket.shutdownInput();
  43. //服务器端响应数据
  44. System.out.println("请回复需要响应的内容:");
  45. str = sc.nextLine();
  46. bw.write(str);//发送数据
  47. bw.flush(); //刷新流
  48. socket.shutdownOutput();
  49. }
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }finally {
  53. if (bw!=null){
  54. try {
  55. bw.close();
  56. } catch (IOException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. if (br!=null){
  61. try {
  62. br.close();
  63. } catch (IOException e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. if (os!=null){
  68. try {
  69. os.close();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. if (is!=null){
  75. try {
  76. is.close();
  77. } catch (IOException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81. if (serverSocket!=null){
  82. try {
  83. serverSocket.close();
  84. } catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. }
  88. if (socket!=null){
  89. try {
  90. socket.close();
  91. } catch (IOException e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }
  96. }
  97. }