当前位置:   article > 正文

Java程序设计实验六 Socket网络程序设计

实验六 socket网络程序设计

[1]实验目的:理解Socket通信原理,掌握使用Socket和ServerSocket类进行TCP Socket通信的程序设计方法。

[2]实验内容

1、使用ServerSocket类和Socket类实现按如下协议通信的服务器端和客户端程序。

服务器程序的处理规则如下:

  1. 向客户端程序发送Verifying Server!。
  2. 若读口令次数超过3次,则发送Illegal User!给客户端,程序退出。否则向下执行步骤3)。
  3. 读取客户端程序提供的口令。
  4. 若口令不正确,则发送PassWord Wrong!给客户端,并转步骤2),否则向下执行步骤5)。
  5. 发送Registration Successful!给客户端程序。

客户端程序的处理规则如下:

  1. 读取服务器反馈信息。
  2. 若反馈信息不是Verifying Server!,则提示Server Wrong!,程序退出。否则向下执行步骤3)
  3. 提示输入PassWord并将输入的口令发送给服务器。
  4. 读取服务器反馈信息。
  5. 若反馈信息是Illegal User!,则提示Illegal User!,程序退出。否则向下执行步骤6)
  6. 若反馈信息是PassWord Wrong!,则提示PassWord Wrong!,并转步骤3),否则向下执行步骤。
  7. 输出Registration Successful!。

 服务器端:

  1. package experiment6.exp6_1;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.Objects;
  9. public class Exp6_1_Server {
  10. public static void main(String[] args) throws IOException {
  11. ServerSocket socket = new ServerSocket(6001);
  12. Socket server = socket.accept();
  13. String password;
  14. int count = 0;
  15. PrintWriter out = new PrintWriter(server.getOutputStream(), true);//返回TCP连接提供的字节输出流,将其格式化
  16. BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));//字节输入流转换为字符输入流,
  17. //BufferedReader 提供以缓冲方式读取一行字符串的方法
  18. out.println("Verifying Server!");
  19. while (true) {
  20. password = in.readLine(); //读取客户端数据
  21. System.out.println("Client:" + password);
  22. if (Objects.equals(password, "123456")) {
  23. out.println("Registration Successful!");
  24. System.out.println("Server:Registration Successful!");
  25. System.exit(0);
  26. } else {
  27. count++;
  28. if (count == 3) {
  29. out.println("Illegal User!");
  30. System.out.println("Server: Illegal User!");
  31. break;
  32. } else {
  33. out.println(" PassWord Wrong!");
  34. System.out.println("Server: PassWord Wrong!");
  35. }
  36. }
  37. }
  38. out.close();
  39. in.close();
  40. server.close();
  41. socket.close();
  42. }
  43. }

客户端

  1. package experiment6.exp6_1;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.Socket;
  7. import java.util.Scanner;
  8. public class Exp6_1_Client {
  9. public static void main(String[] args) throws IOException {
  10. Socket ser=new Socket("10.200.229.170",6001);
  11. Scanner scanner =new Scanner(System.in);
  12. String str,sc;
  13. PrintWriter out=new PrintWriter(ser.getOutputStream(),true);
  14. BufferedReader in=new BufferedReader(new InputStreamReader(ser.getInputStream()));
  15. while(true)
  16. {
  17. str=in.readLine();
  18. System.out.println("Server:"+str);
  19. if(str.equals("Illegal User!")||str.equals("Registration Successful!"))
  20. {
  21. break;
  22. }
  23. System.out.print("Client:");
  24. sc= scanner.next();
  25. out.println(sc);
  26. }
  27. out.close();
  28. in.close();
  29. ser.close();
  30. }
  31. }

登录失败情况:

Server:

 

 Client:

登录成功情况:

Server:

 Client:

 

2、实现聊天室功能。

1)完成服务器端和一个客户端之间的聊天功能。

2)扩展部分,采用多线程技术实现一个服务器端和多个客户端之间的聊天功能。

 服务器端

  1. package experiment6.exp6_2;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.Objects;
  11. import java.util.Scanner;
  12. public class server implements Runnable {// 服务端
  13. static List<Socket> socketList= new ArrayList<>();
  14. // 读取 In
  15. static Socket socket = null;
  16. static ServerSocket serverSocket = null;
  17. public server() {// 构造方法
  18. try {
  19. serverSocket = new ServerSocket(9999);
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. int offline =0;
  25. public static void main(String[] args) {
  26. System.out.println("Server");
  27. server t = new server();
  28. System.out.println("Port 9999 remains to be connected......");
  29. int count = 0;
  30. while (true) {
  31. try {
  32. socket = serverSocket.accept();
  33. count++;
  34. System.out.println(count + " client(s) connected successfully!");
  35. socketList.add(socket);
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. Print p = new Print(socket);
  40. Thread read = new Thread(t);
  41. Thread print = new Thread(p);
  42. read.start();
  43. print.start();
  44. }
  45. }
  46. @Override
  47. public void run() {
  48. // 重写run方法
  49. try {
  50. BufferedReader in = new BufferedReader(new InputStreamReader(socket
  51. .getInputStream()));
  52. while (true) {
  53. //接收消息
  54. String jieshou = in.readLine();
  55. if(jieshou == null){
  56. System.out.println("One client got offline");
  57. offline++;
  58. if(offline ==socketList.size()){
  59. System.out.println("All clients offline. Server offline now!");
  60. serverSocket.close();
  61. socket.close();
  62. System.exit(0);
  63. }
  64. break;}
  65. else
  66. System.out.println(jieshou);
  67. //向每一个客户发送接受的消息
  68. for (int i = 0; i < socketList.size(); i++) {
  69. Socket socket = socketList.get(i);
  70. PrintWriter out = new PrintWriter(socket.getOutputStream());
  71. out.println(jieshou);
  72. out.flush();
  73. }
  74. }
  75. } catch (Exception e) {
  76. }
  77. }
  78. }
  79. class Print implements Runnable {
  80. static List<Socket> socketList= new ArrayList<>();
  81. Scanner input = new Scanner(System.in);
  82. public Print(Socket s) {// 构造方法
  83. try {
  84. socketList.add(s);
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. @Override
  90. public void run() {
  91. try {
  92. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  93. while (true) {
  94. String msg = bufferedReader.readLine();
  95. if(Objects.equals(msg, "/quit")) System.exit(0);
  96. for (int i = 0; i < socketList.size(); i++) {
  97. //对每一个客户端发送消息
  98. Socket socket=socketList.get(i);
  99. PrintWriter out = new PrintWriter(socket.getOutputStream());
  100. out.println("Server: "+msg);
  101. out.flush();
  102. }
  103. }
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. }
  107. }
  108. }

客户端

  1. package experiment6.exp6_2;
  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;
  4. import java.io.PrintWriter;
  5. import java.net.Socket;
  6. import java.util.Objects;
  7. import java.util.Scanner;
  8. public class client implements Runnable {// 客户端
  9. static Socket socket = null;
  10. Scanner input = new Scanner(System.in);
  11. String name;
  12. client(String name){this.name=name;}
  13. public void main1() {
  14. System.out.println("Client "+name);
  15. try {
  16. socket = new Socket("localhost", 9999);
  17. System.out.println("Connected!");
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. }
  21. client t = new client(name);
  22. Read r = new Read(socket);
  23. Thread print = new Thread(t);
  24. Thread read = new Thread(r);
  25. print.start();
  26. read.start();
  27. }
  28. @Override
  29. public void run() {
  30. try {
  31. PrintWriter out = new PrintWriter(socket.getOutputStream());
  32. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  33. while (true) {
  34. //向客户端发送消息
  35. String msg = bufferedReader.readLine();
  36. if(Objects.equals(msg, "/quit")){
  37. socket.close();
  38. System.exit(0);
  39. }
  40. out.println(name+": "+msg);
  41. out.flush();
  42. }
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. }
  48. class Read implements Runnable {
  49. static Socket socket = null;
  50. public Read(Socket socket) {
  51. this.socket = socket;
  52. }
  53. @Override
  54. public void run() {
  55. try {
  56. BufferedReader in = new BufferedReader(new InputStreamReader(socket
  57. .getInputStream()));
  58. while (true) {
  59. //接受服务器的消息
  60. System.out.println(in.readLine());
  61. }
  62. } catch (Exception e) {
  63. System.out.println("Server offline! Connection Dismissed!");
  64. System.exit(0);
  65. }
  66. }
  67. }
  68. //client1
  69. package experiment6.exp6_2;
  70. import java.util.Scanner;
  71. public class client1 {
  72. public static void main(String[] args){
  73. System.out.println("请输入昵称:");
  74. Scanner scanner = new Scanner(System.in);
  75. client client_1 = new client(scanner.next());
  76. client_1.main1();
  77. }
  78. }
  79. //client2
  80. package experiment6.exp6_2;
  81. public class client2 {
  82. public static void main(String[] args){
  83. client client_2 = new client("fang");
  84. client_2.main1();
  85. }
  86. }

Server:

 

Client1:

 

Client2:

 

[3]实验分析

第一题比较简单,只有单个客户端和单个服务器端的简单通信,使用PrintWriter返回TCP连接提供的字节输出流,将其格式化,用BufferReader将字节输入流转化为字符输入流,同时提供以缓冲方式读取一行字符串的方法。

对于第二题,为了实现一个服务器端和多个客户端之间的通信,将读和写的功能分别置于两个线程当中,服务器端用一个socket列表来存放与所有客户端建立连接的socket,每发生一个连接,启动新的读写线程来进行通信。客户端和服务器端用BufferReader来进行整行字符串的读取。

在服务器端接收到某个客户端的消息后,还会将其进行转发,发送至每一个客户端,是的所有客户端之间能看见互相发送的消息。同时,为客户端和服务器端设立退出关键字“/quit”,输入“/quit”之后,客户端会关闭socket,结束程序,客户端下线;服务器端则会关闭所有socket,使得所有客户端也被迫退出通信。如果所有客户端均退出,服务器端自动关闭。

客户端也具备自己决定昵称的功能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/147324
推荐阅读
相关标签
  

闽ICP备14008679号