Java基础-24-网络编程2

Java基础-网络编程

网络编程2

1、网络编程(TCP-上传图片)

需求:上传图片 客户端:

(1)、服务端点
(2)、读取客户端已有的图片数据。
(3)、通过socket输出流将数据发给服务端
(4)、读取服务端反馈信息。
(5)、关闭资源。

测试代码:

import java.io.*;
import java.net.*;
class PicClient
{
    public static void main(String [] args)throws Exception
    {
        Socket s = new Socket("192.168.88.1",10003);

        FileInputStream fis = new FileInputStream("c:\\1.bmp");

        OutputStream out = s.getOutputStream();
        byte [] buf = new byte[1024];
        int len = 0 ; 
        while ((len = fis.read(buf))!=-1)
        {
            out.write(buf,0,len);
        }
        //告诉服务端数据已经写完。
        s.shutdownOutput();
        InputStream in = s.getInputStream();
        byte[]bufIn = new byte[1024];
        int num = in.read(bufIn);
        System.out.println(new String(bufIn,0,num));
        fis.close();
        s.close();
    }
}

class PicServer
{
    public static void main(String []args)throws Exception
    {
        ServerSocket ss = new ServerSocket(10003);
        Socket s = ss.accept();
        InputStream in = s.getInputStream();
        FileOutputStream fos = new FileOutputStream("D:\\server.bmp");
        byte[]buf = new byte[1024];
        int len = 0 ;
        while((len = in.read(buf))!=-1)
        {
            fos.write(buf,0,len);
        }
        OutputStream out = s.getOutputStream();
        out.write("上传成功!".getBytes());
        fos.close();
        s.close();
        ss.close();
    }
}

输出结果:

2、网络编程(TCP-客户端并发上传图片)

上一节的服务端有个局限性。当A客户连接上以后,被服务端获取到,服务端执行具体流程,这时B客户端连接,只有等待。因为服务端还没处理完A客户端的请求,还有循环回来执行下次accept方法。所以暂时获取不到B客户端对象。那么为了可以让多个客户端同时并发访问服务端,那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端的请求。

那么如何定义线程呢? 只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入到run方法中。

Demo

import java.io.*;
import java.net.*;
class PicClient_1
{
    public static void main(String [] args)throws Exception
    {
        if(args.length!=1)
        {
            System.out.println("请选择一个jpg格式的图片。");
            return ;

        }
        File file = new File(args[0]);
        if(!(file.exists()&&file.isFile()))
        {
            System.out.println("该文件有问题,要么不存在,要么不是文件");
            return ;
        }
        if(!file.getName().endsWith(".jpg"))
        {
            System.out.println("图片格式错误,请重新选择");
            return ;
        }
        if(file.length()>1024*1024*5)
        {
            System.out.println("文件过大,没安好心。");
            return ;
        }
        Socket s = new Socket("192.168.88.1",10003);
        FileInputStream fis = new FileInputStream(file);
        OutputStream out = s.getOutputStream();
        byte [] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf))!=-1)
        {
            out.write(buf,0,len);
        }

        //告诉服务端数据写完。
        s.shutdownOutput();

        InputStream in = s.getInputStream();
        byte[]bufIn = new byte[1024];
        int num = in.read(bufIn);
        System.out.println(new String(bufIn,0,num));
        fis.close();
        s.close();
    }
}

//定义线程
class PicThread implements Runnable
{
    private Socket s ;
    PicThread(Socket s )
    {
        this.s = s ;
    }
    public void run ()
    {
        int count = 1;
        String ip = s.getInetAddress().getHostAddress();
        try
        {
            System.out.println(ip+"....connected!");
            InputStream in = s.getInputStream();
            File file = new File("D:\\"+ip+"("+(count)+")"+".jpg");
            while(file.exists())
            {
                file = new File("D:\\"+ip+"("+(count++)+")"+".jpg");
            }
            FileOutputStream fos = new FileOutputStream(file);
            byte [] buf = new byte[1024];
            int len  = 0;
            while((len= in.read(buf))!=-1)
            {
                fos.write(buf,0,len);
            }
            OutputStream out = s.getOutputStream();
            out.write("上传成功".getBytes());
            fos.close();
            s.close();
        }
        catch (Exception e)
        {
            throw new RuntimeException(ip+"上传失败");
        }
    }
}
class PicServer_1
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss =new  ServerSocket(10003);
        while(true)
        {
            Socket s = ss.accept();
            new Thread(new PicThread(s)).start();
        }
    }
}

输出结果: 

3、网络编程(TCP-客户端并发登陆)

客户端通过键盘录入用户名,服务端对这个用户名进行校验。

如果该用户存在,在用户端显示xxx,已登录。并在客户端显示xxx,欢迎光临。

如果该用户存在,在服务器端显示xxx,尝试登陆,并在客户端显示xxx,该用户不存在

最多登陆3次。

测试代码:

import java.io.*;
import java.net.*;
class LoginClient
{
    public static void main(String [] args)throws Exception
    {
        Socket s = new Socket("192.168.88.1",10003);
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
        for(int x = 0;x<3;x++)
        {
            String line = bufr.readLine();
            if(line == null)
            {
                break;
            }
            out.println(line);
            String info = bufIn.readLine();
            if(info.contains("欢迎"))
            {
                break;
            }
        }
        bufr.close();
        s.close();
    }
}

class UserThread implements Runnable
{
    private Socket s ;
    UserThread(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 bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
                String name = bufIn.readLine();
                if(name ==null)
                {
                    break;
                }
                BufferedReader bufr = new BufferedReader (new FileReader("D:\\user.txt"));
                PrintWriter out = new PrintWriter(s.getOutputStream(),true);
                String line = null;
                boolean flag = false;
                while((line = bufr.readLine())!=null)
                {
                    if(line.equals(name))
                    {
                        flag =true;
                        break;
                    }
                }
                if(flag)
                {
                    System.out.println(name+",已登录");
                    out.println(name+",欢迎光临");
                    break;
                }
                else 
                {
                    System.out.println(name+",尝试登陆");
                    out.println(name+",用户名不存在");
                }
            }
            s.close();
        }
        catch (Exception e )
        {
            throw new RuntimeException("校验失败");
        }
    }
}

class LoginServer
{
    public static void main(String [] args)throws Exception
    {
        ServerSocket ss = new ServerSocket(10003);
        while(true)
        {
            Socket s = ss.accept();
            new Thread(new UserThread(s)).start();
        }
    }
}

 输出结果: 

4、网络编程(浏览器客户端-自定义服务端)

演示客户端和服务端

(1)、客户端:浏览器IE:直接输入192.168.88.1:10003
(2)、服务端:自定义

测试代码:

import java.net.*;
import java.io.*;
class ServerDemo
{
    public static void main(String[] args)throws Exception
    {
        ServerSocket ss = new ServerSocket(10003);
        Socket s = ss.accept();
        System.out.println(s.getInetAddress().getHostAddress());
        PrintWriter out =new PrintWriter(s.getOutputStream(),true);
        out.println("客户端您好");
        s.close();
        ss.close();
    }
}

输出结果:

5、网络编程(自定义浏览器-Tomcat服务器)

客户端:自定义浏览器 服务端:Tomcat服务器 首先,要模拟一个IE浏览器,就要了解浏览器是怎么样和服务器进行交互的,我们通过在IE浏览器上输入:http://localhost:10003去访问下面代码,就可以截取浏览器的访问信息,因此可以模拟IE与其他服务器交互的信息。

测试代码:

import java.io.*;
import java.net.*;
class ServerInfoRece
{
    public static void main(String [] args)throws Exception
    {
        ServerSocket ss = new ServerSocket(10003);
        Socket s = ss.accept();
        System.out.println(s.getInetAddress().getHostAddress());
        InputStream in = s.getInputStream();
        byte[]buf = new byte[1024];
        int len = in.read(buf);
        System.out.println(new String (buf,0,len));

        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("客户端您好");
        s.close();
        ss.close();
    }
}

输出结果:

由此可见:自定义服务器接收到了以下信息:

0:0:0:0:0:0:0:1
GET / HTTP/1.1
Host: localhost:10003
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/31.0.1650.63 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8

由此可以模仿以上模式编下一个浏览器去访问Tomcat服务器。

测试代码:

import java.io.*;
import java.net.*;
class MyIE
{
    public static void main(String[]args)throws Exception
    {
        Socket s= new Socket("192.168.88.1",8080);
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("GET /myWeb/Hello.html HTTP/1.1");
        out.println("Accept:*/*");
        out.println("Accept-Language: zh-CN,zh;q=0.8");
        out.println("Host:192.168.88.1:10003");
        out.println("Connection:Closed");
        out.println();//制造空格
        out.println();//制造空格

        BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream(),"UTF-8"));
        String line = null;
        while((line = bufr.readLine())!=null)
        {
            System.out.println(line);
        }
        s.close();
    }
}

以上代码的含义,该自定义IE欲访问的资源是服务器Tomcat上的资源,该服务器的端口是8080,然后给服务器发去浏览器的识别信息,即IE欲访问服务器,并请求获取在8080端口下myWeb文件夹下的Hello.html资源,因此在此路径要存在一个名为Hello.html的文件,里面内容如下,最后把内容打印在自定义IE的控制台上。

<!DOTTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML>
<HEAD> 
<TITLE>HTML 测试</TITLE> 
</HEAD> 
<BODY BGCOLOR="#FDF5E6"> 
<H1>HTML 测试</H1> 欢迎。 
</BODY> 
</HTML>

输出结果:

6、网络编程(自定义图形界面浏览器-Tomcat服务器)

Demo

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyIEByGUI
{
    private Frame f ;
    private TextField tf ;
    private Button but ;
    private TextArea ta;

    private Dialog d ;
    private Label lab;
    private Button okBut;
    MyIEByGUI()
    {
        init();
    }
    public void init()
    {
        f = new Frame("my Internet Explorer");
        f.setBounds(300,100,600,500);
        f.setLayout(new FlowLayout());

        tf = new TextField(60);
        but = new Button("转到");
        ta = new TextArea(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);

        f.add(tf);
        f.add(but);
        f.add(ta);

        myEvent();
        f.setVisible(true);
    }
    private void myEvent()
    {
        okBut.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                d.setVisible(false);
            }
        });
        d.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                d.setVisible(false);
            }
        });
        tf.addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e)
            {
                try
                {
                    if(e.getKeyCode() == KeyEvent.VK_ENTER)
                    {
                        showDir();
                    }
                }
                catch (Exception ex)
                {

                }
            }
        });
        but.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    showDir();

                }
                catch (Exception ex)
                {
                }
            }
        });
        f.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
    }
    private void showDir()throws Exception
    {
        ta.setText("");
        String url = tf.getText();//http://192.168.88.1:8080/myWeb/Hello.html
        int index1 = url.indexOf("//")+2;
        int index2 = url.indexOf("/",index1);

        String str = url.substring(index1,index2);//192.168.88.1:8080
        String [] arr = str.split(":");
        String host = arr[0];
        int port = Integer.parseInt(arr[1]);

        String path = url.substring(index2);
        //ta.setText(str+"..."+path);

        Socket s = new Socket(host,port);
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);
        out.println("GET /"+path+" HTTP/1.1");
        out.println("Accept:*/*");
        out.println("Accept-Language: zh-CN,zh;q=0.8");
        out.println("Host:192.168.88.1:10003");
        out.println("Connection:Closed");
        out.println();//制造空格
        out.println();//制造空格

        BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String line = null;
        while((line = bufr.readLine())!=null)
        {
            System.out.println(line);
            ta.append(line+"\r\n");
        }
        ta.append("OVER");//结束标志
        s.close();
    }
    public static void main(String[]    args)throws Exception
    {
        new MyIEByGUI();
    }
}

输出结果:

7、网络编程(URL类和URLConnection类)

java.net.URL URL类:类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

String getFile();//获取此 URL 的文件名。
String getHost();//获取此 URL 的主机名(如果适用)。
String getPath();//获取此 URL 的路径部分。
String getPort();//获取此 URL 的端口号。
String getProtocol();//获取此 URL 的协议名称。
String getQuery();// 获取此 URL 的查询部分。

测试代码:

import java.net.*;
class URLDemo
{
    public static void main(String[]args)throws MalformedURLException
    {
        URL url = new URL("http://192.168.88.1:8080/myWeb/Hello.html?name =haha&age=30");
        System.out.println("getProtocol():"+url.getProtocol());
        System.out.println("getHost():"+url.getHost());
        System.out.println("getPort():"+url.getPort());
        System.out.println("getPath():"+url.getPath());
        System.out.println("getFile():"+url.getFile());
        System.out.println("getQuery():"+url.getQuery());
    }
}

输出结果:

令外一个很实用的类URLConnection,在于Java网络编程中非常实用,而且是在应用层上的使用,例如,下面的例子也同样提取8080端口服务器的html文件,可是提取出来的文件不带有传输层上文件的提示信息。

测试代码:

import java.net.*;
import java.io.*;
class URLConnectionDemo
{
    public static void main(String [] args)throws Exception
    {
        URL url = new URL("http://192.168.88.1:8080/myWeb/Hello.html");
        URLConnection conn = url.openConnection();
        System.out.println(conn);
        InputStream in = conn.getInputStream();
        byte[]buf = new byte[1024];
        int len = in.read(buf);
        System.out.println(new String (buf,0,len));
    }
}

输出结果:

把前面图形化的IE例子里的showDir()代码改进后调试如下:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyIEByGUI_NEW
{
    private Frame f ;
    private TextField tf ;
    private Button but ;
    private TextArea ta;

    private Dialog d ;
    private Label lab;
    private Button okBut;
    MyIEByGUI_NEW()
    {
        init();
    }
    public void init()
    {
        f = new Frame("my Internet Explorer");
        f.setBounds(300,100,600,500);
        f.setLayout(new FlowLayout());

        tf = new TextField(60);
        but = new Button("转到");
        ta = new TextArea(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);

        f.add(tf);
        f.add(but);
        f.add(ta);

        myEvent();
        f.setVisible(true);
    }
    private void myEvent()
    {
        okBut.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                d.setVisible(false);
            }
        });
        d.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                d.setVisible(false);
            }
        });
        tf.addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent e)
            {
                try
                {
                    if(e.getKeyCode() == KeyEvent.VK_ENTER)
                    {
                        showDir();
                    }
                }
                catch (Exception ex)
                {

                }
            }
        });
        but.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    showDir();

                }
                catch (Exception ex)
                {
                }
            }
        });
        f.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
    }
    private void showDir()throws Exception
    {
        ta.setText("");
        String urlPath = tf.getText();//http://192.168.88.1:8080/myWeb/Hello.html
        URL url = new URL(urlPath);
        URLConnection conn = url.openConnection();
        InputStream in = conn.getInputStream();
        byte [] buf = new byte[1024];
        int len = in.read(buf);
        System.out.println(new String(buf,0,len));
        ta.setText(new String(buf,0,len));

    }
    public static void main(String[]args)throws Exception
    {
        new MyIEByGUI_NEW();
    }
}

输出结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值