A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

5黑马币
/*
需求:
在客户端,输入用户名,如果该用户名在系统数据库存在,则提示欢迎登陆,如果不存在,则提示用户不存在,每个IP限制登陆三次
*/
import java.io.*;
import java.net.*;
class LoginClient
{
        public static void main(String[] args)throws Exception
        {
                Socket s=new Socket("192.168.100.100",10001);
                String line=null;
                String info=null;
                        //创建客户端源为控制台的读入流
                BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
                        //创建打印流,将控制台读入的数据打印到网络输出流
                PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
                        //创建带缓冲器的网络输入流,用来读取服务端反馈的数据
                BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
                while(true){
                        line=br.readLine();
               
                        if(line==null)
                                break;
                        if("over".equals(line))
                                break;
                        pw.println(line);
                        //将服务器端反馈的信息输出在控制台上
                        info=bufin.readLine();
                        System.out.println(info);
                        if(info.contains("欢迎"))
                                break;
                        
                        
                        //br.close();

                }
                s.close();
        
        }
}
class LoginServer
{
        public static void main(String[] args)throws Exception
        {
                //创建服务器端Socket服务
                ServerSocket ss=new ServerSocket(10001);
                while(true){
                        //当服务器端接收到一个客户端对象时,则开启一个子线程,处理客户端请求
                        Socket s=ss.accept();
                        new Thread(new LoginUser(s)).start();
                }
        }
}
class LoginUser implements Runnable
{
        private Socket s;
        LoginUser(Socket s){
                this.s=s;
        }
        public void run(){
                String ip=s.getInetAddress().getHostAddress();
                System.out.println(ip+":connected");
                try{
                        for(int x=0;x<3;x++){
                                //创建服务端读取流缓冲器,关联网络输入流,来读取客户端输入的数据
                                BufferedReader brIn=new BufferedReader(new InputStreamReader(s.getInputStream()));

                                
                                //创建服务器端读取流缓冲器,关联文件读取流,来读取指定文件数据
                                BufferedReader br=new BufferedReader(new FileReader("D:\\Mysql.txt"));
                                //创建打印流,关联客户端网络输出流,来将反馈信息打印到网络输出流传递给客户端
                                PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
                                String name=brIn.readLine();

                                String line=null;
                                //添加标记
                                boolean flag=false;
                                //判断客户端输入的用户名称,在服务器端数据库是否存在
                                while((line=br.readLine())!=null){
                                        if(name.equals(line)){
                                                flag=true;
                                                break;
                                        }
                                }
                                if(flag==true){
                                        System.out.println(name+"已登陆");
                                        pw.println(name+":欢迎登陆");
                                        break;
                                }
                                else{
                                        System.out.println(name+":尝试登陆");
                                        pw.println(name+"用户不存在");
                                        break;
                                }
                        
                        }
                        s.close();
                }
                catch(Exception e){
                        throw new RuntimeException("用户校验失败");
                }
        }
}
服务器端主线程进来后就一直处于等待状态了,而客户端,我把while循环放在开始读控制台输入的地方,依然是不行,按理说如果客户端输入的用户名不符,客户端应该是可以再次输入的,因为客户端线程还没有断开,会去重复等待读控制台输入的内容,直到达到3次,才会被服务器端关闭socket,可是我运行第二次就抛异常了,很不解!

最佳答案

查看完整内容

给你改了,自己看吧。 ps:我真无聊。。。

8 个回复

倒序浏览
给你改了,自己看吧。
ps:我真无聊。。。
  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.io.PrintWriter;
  4. import java.net.Socket;

  5. class LoginClient {
  6.         public static void main(String[] args) throws Exception {
  7.                 Socket s = new Socket("127.0.0.1", 10001);

  8.                 String line = null;
  9.                 String info = null;

  10.                 // 创建客户端源为控制台的读入流
  11.                 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

  12.                 // 创建打印流,将控制台读入的数据打印到网络输出流
  13.                 PrintWriter pw = new PrintWriter(s.getOutputStream(), true);

  14.                 // 创建带缓冲器的网络输入流,用来读取服务端反馈的数据
  15.                 BufferedReader bufin = new BufferedReader(new InputStreamReader(s.getInputStream()));

  16.                 while (true) {
  17.                         line = br.readLine();

  18.                         // if (line == null)
  19.                         // break;
  20.                         if ("over".equals(line)) {
  21.                                 s.shutdownOutput();
  22.                                 break;
  23.                         }

  24.                         pw.println(line);

  25.                         // 将服务器端反馈的信息输出在控制台上
  26.                         info = bufin.readLine();
  27.                         System.out.println(info);

  28.                         if (info.contains("欢迎"))
  29.                                 break;

  30.                         // br.close();
  31.                 }

  32.                 // br.close();
  33.                 // pw.close();
  34.                 // bufin.close();
  35.                 s.close();
  36.         }
  37. }


  38. import java.io.BufferedReader;
  39. import java.io.FileReader;
  40. import java.io.InputStreamReader;
  41. import java.io.PrintWriter;
  42. import java.net.Socket;

  43. public class LoginUser implements Runnable {
  44.         private static Socket s;
  45.         private static int count = 0;

  46.         public LoginUser(Socket s) {
  47.                 this.s = s;
  48.         }

  49.         public void run() {
  50.                 func();
  51.         }

  52.         synchronized public static void func() {
  53.                 String ip = s.getInetAddress().getHostAddress();
  54.                 System.out.println(ip + ":connected");
  55.                 try {
  56.                         // 创建服务端读取流缓冲器,关联网络输入流,来读取客户端输入的数据
  57.                         BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

  58.                         // 创建服务器端读取流缓冲器,关联文件读取流,来读取指定文件数据
  59.                         BufferedReader br = new BufferedReader(new FileReader("D:\\Mysql.txt"));

  60.                         // 创建打印流,关联客户端网络输出流,来将反馈信息打印到网络输出流传递给客户端
  61.                         PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
  62.                         String name = brIn.readLine();

  63.                         String line = "";

  64.                         boolean flag = false;
  65.                         // 判断客户端输入的用户名称,在服务器端数据库是否存在
  66.                         while (true) {
  67.                                 while ((line = br.readLine()) != null) {
  68.                                         if (name.equals(line)) {
  69.                                                 flag = true;
  70.                                                 break;
  71.                                         }
  72.                                 }
  73.                                 if (flag == true) {
  74.                                         System.out.println(name + "已登陆");
  75.                                         pw.println(name + ":欢迎登陆");
  76.                                         break;
  77.                                 } else {
  78.                                         count++;
  79.                                         if (count < 3) {
  80.                                                 System.out.println(name + ":尝试登陆");
  81.                                                 pw.println(name + "用户不存在!");
  82.                                         } else {
  83.                                                 System.out.println(name + ":尝试登陆");
  84.                                                 System.out.println("该IP已出错三次,结束本次登录!");
  85.                                                 pw.println(name + "用户不存在!该IP已出错三次,结束本次登录!"); // 注意,无法发送两条信息,因为客户端设置的是先发再收,一次一条。

  86.                                                 s.shutdownOutput();
  87.                                                 break;
  88.                                         }
  89.                                 }
  90.                                 name = brIn.readLine();
  91.                         }

  92.                         s.close();
  93.                         count = 0;
  94.                 } catch (Exception e) {
  95.                         throw new RuntimeException("用户校验失败");
  96.                 }
  97.         }
  98. }
  99. import java.net.ServerSocket;
  100. import java.net.Socket;

  101. public class LoginServer {
  102.         public static void main(String[] args) throws Exception {
  103.                 // 创建服务器端Socket服务
  104.                 ServerSocket ss = new ServerSocket(10001);
  105.                 while (true) {
  106.                         // 当服务器端接收到一个客户端对象时,则开启一个子线程,处理客户端请求
  107.                         Socket s = ss.accept();
  108.                         new Thread(new LoginUser(s)).start();
  109.                 }
  110.         }
  111. }
复制代码
回复 使用道具 举报
这么大串代码看着头晕啊
回复 使用道具 举报
Doug 发表于 2015-9-11 16:41
给你改了,自己看吧。
ps:我真无聊。。。

非常感谢,我知道问题出在哪里了!我只要把run()方法里面的break,去掉,然后再在else里面再添加一个条件判断,如果x=2,那么就关掉客户端的输出流,并返回给客户端,次数达到限制,否则,就返回客户端用户名不正确,然后让线程继续,而不知直接退出来关掉客户端连接!
有两处疑惑,自己刚发现的:
1、我的那个run()方法里面的第一个while循环,是一个阻塞式循环,如果接受到的用户名不存在,应该一直在while里面死等啊,怎么跳出来的,是不是我刚学一个月,把之前的哪里忘掉了?
2、看到你在run()方法里面调用了一个独立的func()方法,并对其多线程同步,我想了一下,服务器确实是支持多线程操作,但是各个线程之间不存在共享数据,应该不需要加这个同步吧?
回复 使用道具 举报
Doug 发表于 2015-9-11 16:41
给你改了,自己看吧。
ps:我真无聊。。。

追加一个问题。真实开发的情况下,遇到这种请款是怎么处理的?应该不会关掉对方的socket吧,是不是在服务器端做一个数据统计,比如限定5次,就抛给他一个改密码的链接,超过6次就把账号冻结?
回复 使用道具 举报
Adualtbird 发表于 2015-9-11 20:55
非常感谢,我知道问题出在哪里了!我只要把run()方法里面的break,去掉,然后再在else里面再添加一个条件 ...

1、第一个while循环,是读取文本文件,读完了也就结束了。
2、我不习惯在run()中写大段代码,所以单独弄个方法;加同步只是个习惯。
回复 使用道具 举报
Doug 中级黑马 2015-9-12 10:39:16
7#
Adualtbird 发表于 2015-9-11 21:34
追加一个问题。真实开发的情况下,遇到这种请款是怎么处理的?应该不会关掉对方的socket吧,是不是在服务 ...

参照银行登录,密码出错超过三次就冻结该账号的登录。
回复 使用道具 举报
Doug 发表于 2015-9-12 10:39
参照银行登录,密码出错超过三次就冻结该账号的登录。

好的,明白了,非常感谢!
回复 使用道具 举报
好厉害 看的我都头疼了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马