本帖最后由 曹睿翔 于 2013-6-9 09:42 编辑
- <P> 搜集知识点范围:客户端并发登陆、浏览器客户端与自定义服务器练习。</P>
- <P>
- 一、客户端并发登陆:</P>
- <P>前提,要有存储用户信息的数据库放在服务端。当用户输入自己的用户名和密码时,该信息通过IO流传送到服务端,服务端将信息与数据库中的数据进行比对,若正确,返回true,允许登陆,否则,返回false。并发则体现在同时可以有多个用户进行提交,也可以是一个用户提交多次,但最多为3次,防止恶意攻击服务器,用多线程来进行实现。</P>
- <P>中心思想:
- 客户端:完成用户的输入,并将信息传给服务器,在传输之前进行简单的验证,防止穿空信息;要创建自己的套接字,绑定主机ip和指定端口号
- 服务端:接受客户端传来的信息,读取数据库,判断登陆是否成功,将结果反馈给用户
- 客户端线程:用来实现多用户并发登陆功能</P>
- <P>代码如下:</P>
- <P>//客户端
- class Client
- {
- public static void main(String[] args) throws UnknowHostException,IOException
- {
- Socket s = new Socket("180.125.239.175",10008);//创建客户端套接字,180.125.239.175是我本机的ip地址,10008是指定的端口号
- PrintStream ps = new PrintStream(s.getOutputStream(),true);//把客户端输入的信息发给服务端
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//读取键盘录入
- BufferedReader bur = new BufferedReader(new InputStreamReader(s.getInputStream()));//接收客户端反馈给的信息</P>
- <P> //只允许客户端错误提交三次,用for循环进行限制
- for(int i=0; i<3; i++){
- String line = br.readLine();//读取客户端的录入信息
- if(line == null)//判断空,防止发空的信息到服务端
- break;
- ps.println(line);//把客户端信息传到服务端</P>
- <P> String info = bur.readLine();//服务端的信息</P>
- <P> System.out.println("info:" + info);//返回服务端的信息
- if(info.contains("welcome"))//判断登陆是否成功
- break;
- }
- //校验过三次之后关闭
- pr.close();
- s.close();
- }
- }</P>
- <P>//定义多用户线程
- class UserThread implements Runnable
- {
- private Socket s;</P>
- <P> UserThread(Socket s){
- this.s = s;
- }
- //线程的执行方法
- public void run(){
-
- String ip = s.getInetAddress().getHostAddress();//获得传过来的用户的ip</P>
- <P> try{
- //首先要进行验证
- for(int x=0; x<3; x++){
- BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));</P>
- <P> String name = bufIn.readLine();</P>
- <P> BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));//读取数据库</P>
- <P> PrintWriter out = new PrintWriter(s.getOutputStream(),true);//服务端的输出流</P>
- <P> String line = null;
-
- boolean flag = false;//用一个标记来看是否找到用户
- while((line=bufr.readLine())!=null){
- if(line.equals(name)){
- flag = true;
- break;//跳出for循环
- }
- }
- if(flag){//如果登陆成功
- System.out.println(name + "已登录");
- out.println(name+"欢迎光临");
- break;
- }
- else{//如果登陆不成功
- System.out.println(name + "尝试登录");
- out.println(name+"用户名不存在");
- }
- }
- s.close;
- }
- catch(){}
- }
- }</P>
- <P>//服务端
- public class Server{
-
- public static void main(String[] args)
- {
- ServerSocket ss = new ServerSocket(10008);//将服务端的套接字绑定在客户端的端口上进行监听</P>
- <P> while(true){
- Socket s == ss.accept();</P>
- <P> //同时允许多用户进行登陆,将客户端线程封装起来
- new Thread(new UserThread(s)).start();
- }
- }</P>
- <P>}</P>
- <P>二、自定义服务端</P>
- <P>自定义的服务端要求能够与客户端进行连接,接受其发过来的请求或信息,根据需求自定义方法进行处理,并将结果反馈给用户。初学者可以先从简单的功能做起,然后模仿tomcat服务器逐步增加新的功能。简单的自定义服务端示例如下:</P>
- <P>//服务器端
- import java.net.*;
- import java.io.*;
- class ServerDemo
- {
- public static void main(String[] args)throws Exception{</P>
- <P> Socket s = ss.accept();//连接服务端和客户端
- System.out.println(s.getInetAddress().getHostAddress());//输出客户端的地址</P>
- <P> PrintWriter out = new PrintWriter(s.getOutputStream(),true);//服务端输出流</P>
- <P> out.println("客户端你好");//反馈给客户端的信息</P>
- <P> s.close();//关闭客户端套接字</P>
- <P> ss.close();//关闭服务端套接字
-
- }
- }</P>
- <P>//浏览器客户端</P>
- <P>import java.io.*;
- import java.net.*;</P>
- <P>class MyIE{
-
- public static void main(String [] args) throws Exception{
-
- Socket s = new Socket("180.125.239.175",8080);//8080为http上网的默认端口号</P>
- <P> PrintWriter out = new PrintWriter(s.getOutputStream(),true);</P>
- <P> //在java语言中通过输出html的规范语言来形成一个网页
- out.println("GET/myweb/domo.html HTTP/1.1");
- out.println("Accept:");
- out.println("Accept-Language:zh-cn");
- out.println("Host:180.125.239.175:11000");
- out.println("Connection:Keep_Alive");</P>
- <P>
- BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));//输入流</P>
- <P> String line = null;//line属性用来读取客户端输入的内容</P>
- <P> while((line = bufr.readLine())!= null){
- System.out.println(line);
- }
- s.close();//关闭套接字</P>
- <P> }
- }</P>
- <P>
- 三、自定义浏览器
- 除了用传统的“黑窗口”可以与服务端进行交互之外,我们还可以自定义GUI浏览器实现该功能。它主要是讲图形用户接口跟相应的链接类进行对应,当用户点击某一按钮或输入内容时能够达到希望得到的结果。</P>
- <P> 简单的示例如下:</P>
- <P> import java.awt.*;
- import java.awt.event.*;
- import java.io.*;</P>
- <P> class MyIEByGUI
- {
- private Frame f;
- private TextField tf;
- private Button but;
- private TextArea ta;</P>
- <P> private Dialog d;
- private Label lab;
- private Button okBut;</P>
- <P> MyIEByGUI(){//构造方法
-
- init();
-
- }</P>
- <P> public void init(){//构造方法中调用的初始化方法
-
- f =new Frame("my window");
- f.setBounds(300,100,600,500);//设置frame边框大小
- f.setLayout(new FlowLayout());//设置布局为流式布局</P>
- <P> tf = new TextField(60);//文本框用来输入内容
- but = new Button("转到");//定义一个转到按钮
- ta = new TextArea(25,70);//共25行,每行最多70个字
- d = new Dialog(f,"提示信息 -self",true);//提示信息
- d.setBounds(400,200,240,150);//提示窗口的大小和位置
- d.setLayout(new FlowLayout());//提示窗口的布局
- lab = new Label();//标签
- okBut = new Button("确定");//确定按钮
-
- //将标签和按钮添加到提示框上
- d.add(lab);
- d.add(okBut);</P>
- <P> //将文本域等添加到frame上
- f.add(tf);
- f.add(but);
- f.add(ta);</P>
- <P> myEvent();//自定义动作方法
- f.setVisible(true);//必须将此值设置为true才能显示文本框</P>
- <P> }</P>
- <P> //次方法用来给组建添加监听器
- private void myEvent(){</P>
- <P> //button添加监听器
- okBut.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
- d.setVisible(false);
- }
- });
- //提示框添加窗口监听器
- d.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- d.setVisible(false);
- }
- });
- //文本域添加KeyListener
- tf.addKeyListener(new KeyAdapter(){
- public void keyPressed(KeyEvent e){
- if(e.getKeyCode() == KeyEvent.VK_ENTER)
- showDir();
- }
- });
- //按钮添加动作监听器
- but.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
-
- showDir();</P>
- <P> }
- });
- //窗口设置关闭操作
- f.addWindowListener(new WindowAdapter(){
-
- public void windowClosing(WindowEvent e){
- System.exit(0);
- }
- });
- }</P>
- <P> //
- private void showDir(){
-
- String dirPath = tf.getText();//获取用户输入的内容</P>
- <P> File dir = new File(dirPath);</P>
- <P> if(dir.exists() && dir.isDirectory()){
-
- ta.setText("");
- String[] names = dir.list();
- for(String name : names){
- ta.append(name +"\r\n");
- }</P>
- <P> }
- else{
- String info = "您输入的信息:" + dirPath + "是错误的,请重新输入!";
- lab.setText(info);
- d.setvisible(true);
- }
-
- }</P>
- <P> //主方法体
- public static void main(String[] args){
-
- new MyIEByGUI();
- }
- }</P>
- <P>
- PS:这部分的视频主要带领大家了解B/S和C/S模式,并学会编程实现客户端与服务端的交互,核心原理即通过套接字将客户端与服务端建立连接,然后通过流的方式将客户端请求传递到服务端,服务端经过处理后把结果反馈给用户。</P>
复制代码 |
|