【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. }
相关推荐
浮游本尊2 分钟前
对象、函数、原型之间的关系
开发语言·javascript·原型模式
波澜X5 分钟前
springboot 配置Kafka 关闭自启动连接
java·kafka
白宇横流学长10 分钟前
企业电子投票系统 【源码+文档】
java
网络安全-杰克24 分钟前
以ATT&CK为例构建网络安全知识图
网络·安全·web安全
网络安全queen25 分钟前
网络安全概论——网络安全基础
网络·web安全·php
黑客Jack26 分钟前
网络安全概论——虚拟专网VPN技术
网络·安全·web安全
校园卡已办1 小时前
PHP木马编写
android·开发语言·php
资源补给站1 小时前
大恒相机开发(1)—Python调用采集彩色图像并另存为本地
开发语言·python·数码相机
坚持就是胜利19861 小时前
内网穿透玩法之京东云亚瑟路由器刷神卓互联教程
网络·智能路由器·京东云
咩咩觉主1 小时前
Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定
java·unity·游戏引擎