【Java】网络套接字

网络通信原理--套接字

基于TCP的网络编程

功能:模拟网站的登录,客户端录入账号密码,然后服务器端进行验证。

功能分解1:单向通信

功能:客户端发送一句话到服务器:

客户端:

  1. public class TestClient {//客户端
  2. //这是一个main方法,是程序的入口:
  3. public static void main(String[] args) throws IOException {
  4. //1.创建套接字:指定服务器的ip和端口号:
  5. Socket s = new Socket("192.168.199.217",8888);
  6. //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
  7. OutputStream os = s.getOutputStream();
  8. DataOutputStream dos = new DataOutputStream(os);
  9. //利用这个OutputStream就可以向外发送数据了,但是没有直接发送String的方法
  10. //所以我们又在OutputStream外面套了一个处理流:DataOutputStream
  11. dos.writeUTF("你好");
  12. //3.关闭流 + 关闭网络资源:
  13. dos.close();
  14. os.close();
  15. s.close();
  16. }
  17. }

服务器:

  1. public class TestServer {//服务器
  2. //这是一个main方法,是程序的入口:
  3. public static void main(String[] args) throws IOException {
  4. //1.创建套接字: 指定服务器的端口号
  5. ServerSocket ss = new ServerSocket(8888);
  6. //2.等着客户端发来的信息
  7. Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
  8. //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
  9. //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
  10. //3.感受到的操作流
  11. InputStream is = s.getInputStream();
  12. DataInputStream dis = new DataInputStream(is);
  13. //4.读取客户端发来的数据
  14. String str = dis.readUTF();
  15. System.out.println("客户端发来的数据为:"+str);
  16. //5.关闭流+关闭网络资源
  17. dis.close();
  18. is.close();
  19. s.close();
  20. ss.close();
  21. }
  22. }

测试:

(1)先开启客户端还是先开启服务器:先开服务器,再开启客户端

侧面验证:先开客户端:出错:

功能分解2:双向通信

服务器端:

  1. package com.star.test02;
  2. import java.io.*;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestServer {//服务器
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) throws IOException {
  11. //1.创建套接字: 指定服务器的端口号
  12. ServerSocket ss = new ServerSocket(8888);
  13. //2.等着客户端发来的信息
  14. Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
  15. //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
  16. //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
  17. //3.感受到的操作流
  18. InputStream is = s.getInputStream();
  19. DataInputStream dis = new DataInputStream(is);
  20. //4.读取客户端发来的数据
  21. String str = dis.readUTF();
  22. System.out.println("客户端发来的数据为:"+str);
  23. //向客户端输出一句话:---》操作流---》输出流
  24. OutputStream os = s.getOutputStream();
  25. DataOutputStream dos = new DataOutputStream(os);
  26. dos.writeUTF("你好,我是服务器端,我接受到你的请求了");
  27. //5.关闭流+关闭网络资源
  28. dos.close();
  29. os.close();
  30. dis.close();
  31. is.close();
  32. s.close();
  33. ss.close();
  34. }
  35. }

客户端:

  1. package com.star.test02;
  2. import java.io.*;
  3. import java.net.Socket;
  4. /**
  5. * @author : Starshine
  6. */
  7. public class TestClient {//客户端
  8. //这是一个main方法,是程序的入口:
  9. public static void main(String[] args) throws IOException {
  10. //1.创建套接字:指定服务器的ip和端口号:
  11. Socket s = new Socket("192.168.199.217",8888);
  12. //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
  13. OutputStream os = s.getOutputStream();
  14. DataOutputStream dos = new DataOutputStream(os);
  15. //利用这个OutputStream就可以向外发送数据了,但是没有直接发送String的方法
  16. //所以我们又在OutputStream外面套了一个处理流:DataOutputStream
  17. dos.writeUTF("你好");
  18. //接收服务器端的回话--》利用输入流:
  19. InputStream is = s.getInputStream();
  20. DataInputStream dis = new DataInputStream(is);
  21. String str = dis.readUTF();
  22. System.out.println("服务器端对我说:"+str);
  23. //3.关闭流 + 关闭网络资源:
  24. dis.close();
  25. is.close();
  26. dos.close();
  27. os.close();
  28. s.close();
  29. }
  30. }

注意:关闭防火墙

功能分解3:对象流传送

封装的User类:

  1. package com.star.test03;
  2. import java.io.Serializable;
  3. /**
  4. * @author : Starshine
  5. */
  6. public class User implements Serializable {
  7. private static final long serialVersionUID = 9050691344308365540L;
  8. private String name;
  9. private String pwd;
  10. public String getName() {
  11. return name;
  12. }
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16. public String getPwd() {
  17. return pwd;
  18. }
  19. public void setPwd(String pwd) {
  20. this.pwd = pwd;
  21. }
  22. public User(String name, String pwd) {
  23. this.name = name;
  24. this.pwd = pwd;
  25. }
  26. }

客户端:

  1. package com.star.test03;
  2. import java.io.*;
  3. import java.net.Socket;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestClient {//客户端
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) throws IOException {
  11. //1.创建套接字:指定服务器的ip和端口号:
  12. Socket s = new Socket("192.168.199.217",8888);
  13. //录入用户的账号和密码:
  14. Scanner sc = new Scanner(System.in);
  15. System.out.println("请录入您的账号:");
  16. String name = sc.next();
  17. System.out.println("请录入您的密码:");
  18. String pwd = sc.next();
  19. //将账号和密码封装为一个User的对象:
  20. User user = new User(name,pwd);
  21. //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
  22. OutputStream os = s.getOutputStream();
  23. ObjectOutputStream oos = new ObjectOutputStream(os);
  24. oos.writeObject(user);
  25. //接收服务器端的回话--》利用输入流:
  26. InputStream is = s.getInputStream();
  27. DataInputStream dis = new DataInputStream(is);
  28. boolean b = dis.readBoolean();
  29. if(b){
  30. System.out.println("恭喜,登录成功");
  31. }else{
  32. System.out.println("对不起,登录失败");
  33. }
  34. //3.关闭流 + 关闭网络资源:
  35. dis.close();
  36. is.close();
  37. oos.close();
  38. os.close();
  39. s.close();
  40. }
  41. }

服务器:

  1. package com.star.test03;
  2. import java.io.*;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestServer {//服务器
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) throws IOException, ClassNotFoundException {
  11. //1.创建套接字: 指定服务器的端口号
  12. ServerSocket ss = new ServerSocket(8888);
  13. //2.等着客户端发来的信息
  14. Socket s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
  15. //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
  16. //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
  17. //3.感受到的操作流
  18. InputStream is = s.getInputStream();
  19. ObjectInputStream ois = new ObjectInputStream(is);
  20. //4.读取客户端发来的数据
  21. User user = (User)(ois.readObject());
  22. //对对象进行验证:
  23. boolean flag = false;
  24. if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){
  25. flag = true;
  26. }
  27. //向客户端输出结果:---》操作流---》输出流
  28. OutputStream os = s.getOutputStream();
  29. DataOutputStream dos = new DataOutputStream(os);
  30. dos.writeBoolean(flag);
  31. //5.关闭流+关闭网络资源
  32. dos.close();
  33. os.close();
  34. ois.close();
  35. is.close();
  36. s.close();
  37. ss.close();
  38. }
  39. }
功能分解4:加入完整的处理异常方式

服务器端:

  1. package com.star.test03;
  2. import java.io.*;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestServer {//服务器
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) {
  11. //1.创建套接字: 指定服务器的端口号
  12. ServerSocket ss = null;
  13. Socket s = null;
  14. InputStream is = null;
  15. ObjectInputStream ois = null;
  16. OutputStream os = null;
  17. DataOutputStream dos = null;
  18. try {
  19. ss = new ServerSocket(8888);
  20. //2.等着客户端发来的信息
  21. s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。
  22. //accept()返回值为一个Socket,这个Socket其实就是客户端的Socket
  23. //接到这个Socket以后,客户端和服务器才真正产生了连接,才真正可以通信了
  24. //3.感受到的操作流
  25. is = s.getInputStream();
  26. ois = new ObjectInputStream(is);
  27. //4.读取客户端发来的数据
  28. User user = (User)(ois.readObject());
  29. //对对象进行验证:
  30. boolean flag = false;
  31. if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){
  32. flag = true;
  33. }
  34. //向客户端输出结果:---》操作流---》输出流
  35. os = s.getOutputStream();
  36. dos = new DataOutputStream(os);
  37. dos.writeBoolean(flag);
  38. } catch (IOException | ClassNotFoundException e) {
  39. e.printStackTrace();
  40. } finally {
  41. //5.关闭流+关闭网络资源
  42. try {
  43. if(dos!=null){
  44. dos.close();
  45. }
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. }
  49. try {
  50. if(os!=null){
  51. os.close();
  52. }
  53. } catch (IOException e) {
  54. e.printStackTrace();
  55. }
  56. try {
  57. if(ois!=null){
  58. ois.close();
  59. }
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. try {
  64. if(is!=null){
  65. is.close();
  66. }
  67. } catch (IOException e) {
  68. e.printStackTrace();
  69. }
  70. try {
  71. if(s!=null){
  72. s.close();
  73. }
  74. } catch (IOException e) {
  75. e.printStackTrace();
  76. }
  77. try {
  78. if(ss!=null){
  79. ss.close();
  80. }
  81. } catch (IOException e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. }
  86. }

客户端:

  1. package com.star.test03;
  2. import java.io.*;
  3. import java.net.Socket;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestClient {//客户端
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args){
  11. //1.创建套接字:指定服务器的ip和端口号:
  12. Socket s = null;
  13. OutputStream os = null;
  14. ObjectOutputStream oos = null;
  15. InputStream is = null;
  16. DataInputStream dis = null;
  17. try {
  18. s = new Socket("192.168.199.217",8888);
  19. //录入用户的账号和密码:
  20. Scanner sc = new Scanner(System.in);
  21. System.out.println("请录入您的账号:");
  22. String name = sc.next();
  23. System.out.println("请录入您的密码:");
  24. String pwd = sc.next();
  25. //将账号和密码封装为一个User的对象:
  26. User user = new User(name,pwd);
  27. //2.对于程序员来说,向外发送数据 感受 --》利用输出流:
  28. os = s.getOutputStream();
  29. oos = new ObjectOutputStream(os);
  30. oos.writeObject(user);
  31. //接收服务器端的回话--》利用输入流:
  32. is = s.getInputStream();
  33. dis = new DataInputStream(is);
  34. boolean b = dis.readBoolean();
  35. if(b){
  36. System.out.println("恭喜,登录成功");
  37. }else{
  38. System.out.println("对不起,登录失败");
  39. }
  40. } catch (IOException e) {
  41. e.printStackTrace();
  42. } finally{
  43. //3.关闭流 + 关闭网络资源:
  44. try {
  45. if(dis!=null){
  46. dis.close();
  47. }
  48. } catch (IOException e) {
  49. e.printStackTrace();
  50. }
  51. try {
  52. if(is!=null){
  53. is.close();
  54. }
  55. } catch (IOException e) {
  56. e.printStackTrace();
  57. }
  58. try {
  59. if(oos!=null){
  60. oos.close();
  61. }
  62. } catch (IOException e) {
  63. e.printStackTrace();
  64. }
  65. try {
  66. if(os!=null){
  67. os.close();
  68. }
  69. } catch (IOException e) {
  70. e.printStackTrace();
  71. }
  72. try {
  73. if(s!=null){
  74. s.close();
  75. }
  76. } catch (IOException e) {
  77. e.printStackTrace();
  78. }
  79. }
  80. }
  81. }
功能分解5:多线程接收用户请求

遗留问题:服务器针对一个请求服务,之后服务器就关闭了(程序自然结束了)

现在需要解决:服务器必须一直在监听 ,一直开着,等待客户端的请求

在当前代码中,客户端不用动了

更改服务器代码:

  1. package com.star.test03;

  2. import java.io.*;

  3. import java.net.Socket;

  4. /**

  5. * @author : Starshine

  6. */

  7. public class ServerThread extends Thread {//线程:专门处理客户端的请求

  8. InputStream is = null;

  9. ObjectInputStream ois = null;

  10. OutputStream os = null;

  11. DataOutputStream dos = null;

  12. Socket s = null;

  13. public ServerThread(Socket s){

  14. this.s = s;

  15. }

  16. @Override

  17. public void run() {

  18. try{

  19. //2.等着客户端发来的信息

  20. is = s.getInputStream();

  21. ois = new ObjectInputStream(is);

  22. //4.读取客户端发来的数据

  23. User user = (User)(ois.readObject());

  24. //对对象进行验证:

  25. boolean flag = false;

  26. if(user.getName().equals("娜娜")&&user.getPwd().equals("123123")){

  27. flag = true;

  28. }

  29. //向客户端输出结果:---》操作流---》输出流

  30. os = s.getOutputStream();

  31. dos = new DataOutputStream(os);

  32. dos.writeBoolean(flag);

  33. }catch (IOException | ClassNotFoundException e) {

  34. e.printStackTrace();

  35. }finally {

  36. try {

  37. if(dos!=null){

  38. dos.close();

  39. }

  40. } catch (IOException e) {

  41. e.printStackTrace();

  42. }

  43. try {

  44. if(os!=null){

  45. os.close();

  46. }

  47. } catch (IOException e) {

  48. e.printStackTrace();

  49. }

  50. try {

  51. if(ois!=null){

  52. ois.close();

  53. }

  54. } catch (IOException e) {

  55. e.printStackTrace();

  56. }

  57. try {

  58. if(is!=null){

  59. is.close();

  60. }

  61. } catch (IOException e) {

  62. e.printStackTrace();

  63. }

  64. }

  65. }

  66. }

  67. package com.star.test03;

  68. import java.io.*;

  69. import java.net.ServerSocket;

  70. import java.net.Socket;

  71. /**

  72. * @author : Starshine

  73. */

  74. public class TestServer {//服务器

  75. //这是一个main方法,是程序的入口:

  76. public static void main(String[] args) {

  77. System.out.println("服务器启动了");

  78. //1.创建套接字: 指定服务器的端口号

  79. ServerSocket ss = null;

  80. Socket s = null;

  81. int count = 0;//定义一个计数器,用来计数 客户端的请求

  82. try {

  83. ss = new ServerSocket(8888);

  84. while(true){//加入死循环,服务器一直监听客户端是否发送数据

  85. s = ss.accept();//阻塞方法:等待接收客户端的数据,什么时候接收到数据,什么时候程序继续向下执行。

  86. //每次过来的客户端的请求 靠 线程处理:

  87. new ServerThread(s).start();

  88. count++;

  89. //输入请求的客户端的信息:

  90. System.out.println("当前是第"+count+"个用户访问我们的服务器,对应的用户是:"+s.getInetAddress());

  91. }

  92. } catch (IOException e) {

  93. e.printStackTrace();

  94. }

  95. }

  96. }

基于UDP的网络编程

TCP:

客户端:Socket

程序感受到的 使用流 :输出流

服务器端: ServerSocket --->Socket 程序感受到的 使用流 :输入流

(客户端和服务器端地位不平等。)

UDP:

发送方:DatagramSocket 发送:数据包 DatagramPacket

接收方:DatagramSocket 接收:数据包 DatagramPacket

(发送方和接收方的地址是平等的。)

UDP案例: 完成网站的咨询聊天

功能分解1:单向通信

发送方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. /**
  5. * @author : Starshine
  6. */
  7. public class TestSend {//发送方:
  8. //这是一个main方法,是程序的入口:
  9. public static void main(String[] args) throws IOException {
  10. System.out.println("学生上线。。。");
  11. //1.准备套接字: 指定发送方的端口号
  12. DatagramSocket ds = new DatagramSocket(8888);
  13. //2.准备数据包
  14. String str = "你好";
  15. byte[] bytes = str.getBytes();
  16. /*
  17. 需要四个参数:
  18. 1.指的是传送数据转为字节数组
  19. 2.字节数组的长度
  20. 3.封装接收方的ip
  21. 4.指定接收方的端口号
  22. */
  23. DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
  24. //发送:
  25. ds.send(dp);
  26. //关闭资源
  27. ds.close();
  28. }
  29. }

接收方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.SocketException;
  6. /**
  7. * @author : Starshine
  8. */
  9. public class TestReceive {//接收方
  10. //这是一个main方法,是程序的入口:
  11. public static void main(String[] args) throws IOException {
  12. System.out.println("老师上线了。。");
  13. //1.创建套接字:指定接收方的端口
  14. DatagramSocket ds = new DatagramSocket(9999);
  15. //2.有一个空的数据包,打算用来接收 对方传过来的数据包:
  16. byte[] b = new byte[1024];
  17. DatagramPacket dp = new DatagramPacket(b,b.length);
  18. //3.接收对方的数据包,然后放入我们的dp数据包中填充
  19. ds.receive(dp);//接收完以后 dp里面就填充好内容了
  20. //4.取出数据
  21. byte[] data = dp.getData();
  22. String s = new String(data,0,dp.getLength());//dp.getLength()数组包中的有效长度
  23. System.out.println("学生对我说:"+s);
  24. //5.关闭资源
  25. ds.close();
  26. }
  27. }
功能分解2:双向通信

发送方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestSend {//发送方:
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) throws IOException {
  11. System.out.println("学生上线。。。");
  12. //1.准备套接字: 指定发送方的端口号
  13. DatagramSocket ds = new DatagramSocket(8888);
  14. //2.准备数据包
  15. Scanner sc = new Scanner(System.in);
  16. System.out.print("学生:");
  17. String str = sc.next();
  18. byte[] bytes = str.getBytes();
  19. /*
  20. 需要四个参数:
  21. 1.指的是传送数据转为Z字节数组
  22. 2.字节数组的长度
  23. 3.封装接收方的ip
  24. 4.指定接收方的端口号
  25. */
  26. DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
  27. //发送:
  28. ds.send(dp);
  29. //接收老师发送回来的信息:
  30. byte[] b = new byte[1024];
  31. DatagramPacket dp2 = new DatagramPacket(b,b.length);
  32. ds.receive(dp2);//接收完以后 dp2里面就填充好内容了
  33. //取出数据:
  34. byte[] data = dp2.getData();
  35. String s = new String(data,0,dp2.getLength());//dp.getLength()数组包中的有效长度
  36. System.out.println("老师对我说:"+s);
  37. //关闭资源
  38. ds.close();
  39. }
  40. }

接收方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.InetAddress;
  6. import java.net.SocketException;
  7. import java.util.Scanner;
  8. /**
  9. * @author : Starshine
  10. */
  11. public class TestReceive {//接收方
  12. //这是一个main方法,是程序的入口:
  13. public static void main(String[] args) throws IOException {
  14. System.out.println("老师上线了。。");
  15. //1.创建套接字:指定接收方的端口
  16. DatagramSocket ds = new DatagramSocket(9999);
  17. //2.有一个空的数据包,打算用来接收 对方传过来的数据包:
  18. byte[] b = new byte[1024];
  19. DatagramPacket dp = new DatagramPacket(b,b.length);
  20. //3.接收对方的数据包,然后放入我们的dp数据包中填充
  21. ds.receive(dp);//接收完以后 dp里面就填充好内容了
  22. //4.取出数据
  23. byte[] data = dp.getData();
  24. String s = new String(data,0,dp.getLength());//dp.getLength()数组包中的有效长度
  25. System.out.println("学生对我说:"+s);
  26. //老师进行回复:
  27. Scanner sc = new Scanner(System.in);
  28. System.out.print("老师:");
  29. String str = sc.next();
  30. byte[] bytes = str.getBytes();
  31. //封装数据,并且指定学生的ip和端口号
  32. DatagramPacket dp2 = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),8888);
  33. //发送:
  34. ds.send(dp2);
  35. //5.关闭资源
  36. ds.close();
  37. }
  38. }
功能分解3:加入完整的处理异常方式

发送方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestSend {//发送方:
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) {
  11. System.out.println("学生上线。。。");
  12. //1.准备套接字: 指定发送方的端口号
  13. DatagramSocket ds = null;
  14. try {
  15. ds = new DatagramSocket(8888);
  16. //2.准备数据包
  17. Scanner sc = new Scanner(System.in);
  18. System.out.print("学生:");
  19. String str = sc.next();
  20. byte[] bytes = str.getBytes();
  21. /*
  22. 需要四个参数:
  23. 1.指的是传送数据转为Z字节数组
  24. 2.字节数组的长度
  25. 3.封装接收方的ip
  26. 4.指定接收方的端口号
  27. */
  28. DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
  29. //发送:
  30. ds.send(dp);
  31. //接收老师发送回来的信息:
  32. byte[] b = new byte[1024];
  33. DatagramPacket dp2 = new DatagramPacket(b,b.length);
  34. ds.receive(dp2);//接收完以后 dp2里面就填充好内容了
  35. //取出数据:
  36. byte[] data = dp2.getData();
  37. String s = new String(data,0,dp2.getLength());//dp.getLength()数组包中的有效长度
  38. System.out.println("老师对我说:"+s);
  39. } catch (SocketException e) {
  40. e.printStackTrace();
  41. } catch (UnknownHostException e) {
  42. e.printStackTrace();
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. } finally {
  46. //关闭资源
  47. ds.close();
  48. }
  49. }
  50. }

接收方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestReceive {//接收方
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args){
  11. System.out.println("老师上线了。。");
  12. //1.创建套接字:指定接收方的端口
  13. DatagramSocket ds = null;
  14. try {
  15. ds = new DatagramSocket(9999);
  16. //2.有一个空的数据包,打算用来接收 对方传过来的数据包:
  17. byte[] b = new byte[1024];
  18. DatagramPacket dp = new DatagramPacket(b,b.length);
  19. //3.接收对方的数据包,然后放入我们的dp数据包中填充
  20. ds.receive(dp);//接收完以后 dp里面就填充好内容了
  21. //4.取出数据
  22. byte[] data = dp.getData();
  23. String s = new String(data,0,dp.getLength());//dp.getLength()数组包中的有效长度
  24. System.out.println("学生对我说:"+s);
  25. //老师进行回复:
  26. Scanner sc = new Scanner(System.in);
  27. System.out.print("老师:");
  28. String str = sc.next();
  29. byte[] bytes = str.getBytes();
  30. //封装数据,并且指定学生的ip和端口号
  31. DatagramPacket dp2 = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),8888);
  32. //发送:
  33. ds.send(dp2);
  34. } catch (SocketException e) {
  35. e.printStackTrace();
  36. } catch (UnknownHostException e) {
  37. e.printStackTrace();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. } finally {
  41. //5.关闭资源
  42. ds.close();
  43. }
  44. }
  45. }
功能分解4:正常通信

发送方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestSend {//发送方:
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args) {
  11. System.out.println("学生上线。。。");
  12. //1.准备套接字: 指定发送方的端口号
  13. DatagramSocket ds = null;
  14. try {
  15. ds = new DatagramSocket(8888);
  16. while(true){
  17. //2.准备数据包
  18. Scanner sc = new Scanner(System.in);
  19. System.out.print("学生:");
  20. String str = sc.next();
  21. byte[] bytes = str.getBytes();
  22. /*
  23. 需要四个参数:
  24. 1.指的是传送数据转为Z字节数组
  25. 2.字节数组的长度
  26. 3.封装接收方的ip
  27. 4.指定接收方的端口号
  28. */
  29. DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),9999);
  30. //发送:
  31. ds.send(dp);
  32. if(str.equals("byebye")){
  33. System.out.println("学生下线。。");
  34. break;
  35. }
  36. //接收老师发送回来的信息:
  37. byte[] b = new byte[1024];
  38. DatagramPacket dp2 = new DatagramPacket(b,b.length);
  39. ds.receive(dp2);//接收完以后 dp2里面就填充好内容了
  40. //取出数据:
  41. byte[] data = dp2.getData();
  42. String s = new String(data,0,dp2.getLength());//dp.getLength()数组包中的有效长度
  43. System.out.println("老师对我说:"+s);
  44. }
  45. } catch (SocketException e) {
  46. e.printStackTrace();
  47. } catch (UnknownHostException e) {
  48. e.printStackTrace();
  49. } catch (IOException e) {
  50. e.printStackTrace();
  51. } finally {
  52. //关闭资源
  53. ds.close();
  54. }
  55. }
  56. }

接收方:

  1. package com.star.test04;
  2. import java.io.IOException;
  3. import java.net.*;
  4. import java.util.Scanner;
  5. /**
  6. * @author : Starshine
  7. */
  8. public class TestReceive {//接收方
  9. //这是一个main方法,是程序的入口:
  10. public static void main(String[] args){
  11. System.out.println("老师上线了。。");
  12. //1.创建套接字:指定接收方的端口
  13. DatagramSocket ds = null;
  14. try {
  15. ds = new DatagramSocket(9999);
  16. while(true){
  17. //2.有一个空的数据包,打算用来接收 对方传过来的数据包:
  18. byte[] b = new byte[1024];
  19. DatagramPacket dp = new DatagramPacket(b,b.length);
  20. //3.接收对方的数据包,然后放入我们的dp数据包中填充
  21. ds.receive(dp);//接收完以后 dp里面就填充好内容了
  22. //4.取出数据
  23. byte[] data = dp.getData();
  24. String s = new String(data,0,dp.getLength());//dp.getLength()数组包中的有效长度
  25. System.out.println("学生对我说:"+s);
  26. if(s.equals("byebye")){
  27. System.out.println("学生已经下线了,老师也下线。。。");
  28. break;
  29. }
  30. //老师进行回复:
  31. Scanner sc = new Scanner(System.in);
  32. System.out.print("老师:");
  33. String str = sc.next();
  34. byte[] bytes = str.getBytes();
  35. //封装数据,并且指定学生的ip和端口号
  36. DatagramPacket dp2 = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("localhost"),8888);
  37. //发送:
  38. ds.send(dp2);
  39. }
  40. } catch (SocketException e) {
  41. e.printStackTrace();
  42. } catch (UnknownHostException e) {
  43. e.printStackTrace();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. } finally {
  47. //5.关闭资源
  48. ds.close();
  49. }
  50. }
  51. }
相关推荐
charlie11451419111 分钟前
如何使用Qt创建一个浮在MainWindow上的滑动小Panel
开发语言·c++·qt·界面设计
Dcs15 分钟前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java
神仙别闹19 分钟前
基于Python实现LSTM对股票走势的预测
开发语言·python·lstm
保持学习ing21 分钟前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
京东云开发者32 分钟前
Java的SPI机制详解
java
超级小忍1 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
程序无bug1 小时前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享1 小时前
Java Lombok 入门
java
程序无bug1 小时前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队1 小时前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端