网络编程(三)

TCP客服端并发上传图片:

/* 
需求:上传图片。 
*/  
/* 
客户端。 
1,服务端点。 
2,读取客户端已有的图片数据。 
3,通过socket 输出流将数据发给服务端。 
4,读取服务端反馈信息。 
5,关闭。 
*/  
  
import java.io.*;  
import java.net.*;  
class  PicClient  
{  
    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.1.254",10007);  
  
        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();  
    }  
}  
  
/* 
服务端 
 
这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。 
这时B客户端连接,只有等待。 
因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以 
暂时获取不到B客户端对象。 
 
那么为了可以让多个客户端同时并发访问服务端。 
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。 
 
如何定义线程呢? 
 
只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。 
*/  
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 dir =  new File("d:\\pic");  
  
            File file = new File(dir,ip+"("+(count)+")"+".jpg");  
  
            while(file.exists())  
                file = new File(dir,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  
{  
    public static void main(String[] args) throws Exception  
    {  
        ServerSocket ss = new ServerSocket(10007);  
  
        while(true)  
        {  
            Socket s = ss.accept();  
  
            new Thread(new PicThread(s)).start();  
  
          
        }  
  
        //ss.close();  
    }  
}  

客户端并发登陆:

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

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

如果该用户存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。最多就登录三次。

import java.io.*;  
import java.net.*;  
  
  
class  LoginClient  
{  
    public static void main(String[] args) throws Exception  
    {   
        //建立Socket链接  
        Socket s = new Socket("192.168.1.254",10008);  
          
        //读取键盘录入  
        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();  
            System.out.println("info:"+info);  
            if(info.contains("欢迎"))  
                break;  
  
        }  
  
        bufr.close();  
        s.close();  
    }  
}  
  
//客户端分配线程的代码,封装客户端线程的形式就是如此(Tomcat底层原理其中之一)  
class UserThread implements Runnable  
{  
    private Socket s;  
    UserThread(Socket s)  
    {  
        this.s = s;  
    }  
    public void run()  
    {  
        //获得客户端的ip地址  
        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("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(ip+"校验失败");  
        }  
    }  
}  
class  LoginServer  
{  
    public static void main(String[] args) throws Exception  
    {  
        ServerSocket ss = new ServerSocket(10008);  
  
        while(true)  
        {  
            Socket s = ss.accept();  
  
            new Thread(new UserThread(s)).start();  
        }  
    }  
}  

浏览器客户端-自定义服务端:

客户端:浏览器 (telnet)

服务端:自定义

import java.net.*;  
import java.io.*;  
class ServerDemo   
{  
    public static void main(String[] args) throws Exception  
    {  
        ServerSocket ss = new ServerSocket(11000);  
  
        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("<font color='red' size='7'>客户端你好</font>");  
  
        s.close();  
  
        ss.close();  
    }  
}  

浏览器端:

如:输入http://192.168.1.254:10001/

浏览器客户端-Tomcat服务端

     客户端:浏览器客户端。

     服务端:Tomcat服务器。

自定义浏览器-Tomcat服务端

客户端:自定义浏览器。
服务端:Tomcat服务器。

import java.io.*;  
import java.net.*;  
  
/* 
自己定义的客户端 
*/  
class MyIE   
{  
    public static void main(String[] args)throws Exception   
    {  
        Socket s = new Socket("127.0.0.1",8080);  
          
        PrintWriter out = new PrintWriter(s.getOutputStream(),true);  
        //浏览器http请求消息头
        out.println("GET /myweb/demo.html HTTP/1.1");  
        //*/*表示所有的都支持  
        out.println("Accept: */*");  
        out.println("Accept-Language: zh-cn");  
        out.println("Host: 127.0.0.1:11000");  
        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);  
        }  
  
        s.close();  
  
  
  
  
    }  
}  

自定义图形界面浏览器-Tomcat服务端:

客户端:自定义图形界面浏览器
服务端:Tomcat服务器。

/* 
浏览器是应用层的软件,而我们的Socket走的是传输层,传输层的协议带有应用层的消息头 
所以显示的信息比较多 
*/  
  
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 window");  
        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.1.254:8080/myweb/demo.html  
          
        int index1 = url.indexOf("//")+2;  
  
        int index2 = url.indexOf("/",index1);  
  
  
  
        String str = url.substring(index1,index2);  
        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");  
        out.println("Host: 127.0.0.1:11000");  
        out.println("Connection: closed");  
  
        out.println();  
        out.println();  
  
        BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));  
  
        String line = null;  
  
        while((line=bufr.readLine())!=null)  
        {  
            //在控制台打印出来  
            ta.append(line+"\r\n");  
        }  
  
        s.close();  
  
    }  
  
    public static void main(String[] args)   
    {  
        new MyIEByGUI();  
    }  
}  
URL---URLConnection

URI:范围更大,条形码也包含于此范围

URL:范围较小,即域名

import java.net.*;  
class URLDemo   
{  
    public static void main(String[] args) throws MalformedURLException  
    {  
        URL url = new URL("http://192.168.1.254/myweb/demo.html?name=haha&age=30");  
  
        //获取协议http  
        System.out.println("getProtocol() :"+url.getProtocol());  
        //获取主机192.168.1.254  
        System.out.println("getHost() :"+url.getHost());  
        //获取端口  
        System.out.println("getPort() :"+url.getPort());  
        //获取路径myweb/demo.html  
        System.out.println("getPath() :"+url.getPath());  
        // 获取此 URL 的文件名。myweb/demo.html?name=haha&age=30   
        System.out.println("getFile() :"+url.getFile());  
        //获取此 URL 的查询部name=haha&age=30   
        System.out.println("getQuery() :"+url.getQuery());  
  
        /* 
        url默认不写的时候,返回的是-1,因为要先要对url进行解析,解析不到的端口就定义为-1 
        int port = getPort(); 
        if(port==-1) 
            port = 80; 
 
        getPort()==-1 
        */  
    }  
}  



URLConnection:
import java.net.*;  
import java.io.*;  
class  URLConnectionDemo  
{  
    public static void main(String[] args) throws Exception  
    {  
        URL url = new URL("http://192.168.1.254:8080/myweb/demo.html");  
  
        URLConnection conn = url.openConnection();  //内部封装Socket输入出流
        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));  
  
    }  
}  

用URL和URLConnection重写MyIEByGUI:

import java.awt.*;    
import java.awt.event.*;    
import java.net.*;    
import java.io.*;    
    
class MyIEGUI    
{    
    //创建全局变量    
    private Frame f;    
    private Button but;    
    private TextField tf;    
    private TextArea ta;    
    
    private Dialog d;    
    private Label lab;    
    private Button okBut;    
    
    //构造函数,初始化窗体    
    MyIEGUI()    
    {    
        init();    
    }    
    //创建窗体和组件,并将事件添加进来    
    public void init()    
    {    
        //设置窗体    
        f = new Frame("my window");    
        f.setBounds(300,200,600,500);    
        f.setLayout(new FlowLayout());    
        //创建组件    
        but = new Button("转到");    
        tf = new TextField(60);    
        ta = new TextArea(25,75);    
    
        d = new Dialog(f,"提示信息-self",true);    
        d.setBounds(300,100,300,150);    
        d.setLayout(new FlowLayout());    
        lab = new Label();    
        okBut = new Button("确定");    
    
        //将组件添加到窗体    
        f.add(tf);    
        f.add(but);    
        f.add(ta);    
            
        d.add(lab);    
        d.add(okBut);    
    
        //添加事件    
        myEvent();    
        //设置窗体可见    
        f.setVisible(true);    
    }    
    //常见引发的时间    
    private void myEvent()    
    {    
        //给but添加一个活动监听器    
        but.addActionListener(new ActionListener()    
        {    
            public void actionPerformed(ActionEvent e)    
            {    
                try{    
                    showInfo();    
                }catch (Exception ex){    
                    throw new RuntimeException("客户端登陆失败");    
                }    
        }});    
        okBut.addActionListener(new ActionListener()    
        {    
            public void actionPerformed(ActionEvent e)    
            {    
                d.setVisible(false);    
            }    
        });    
        //给文本框添加键盘事件    
        tf.addKeyListener(new KeyAdapter()    
        {    
            public void keyPressed(KeyEvent e)    
            {    
                try{    
                    if(e.getKeyCode()==KeyEvent.VK_ENTER)    
                        showInfo();    
                }catch (Exception ex){    
                    throw new RuntimeException("客户端登陆失败");    
                }    
            }    
        });    
        //关闭窗体事件    
        f.addWindowListener(new WindowAdapter()    
        {    
            public void windowClosing(WindowEvent e)    
            {    
                System.exit(0);    
            }    
        });    
        d.addWindowListener(new WindowAdapter()    
        {    
            public void windowClosing(WindowEvent e)    
            {    
                d.setVisible(false);    
            }    
        });    
    }    
    private void showInfo()throws Exception    
    {    
    
        ta.setText("");    
        //获取路径    
        String urlPath = tf.getText();//http://192.168.1.101:8080/myweb/myIE.html    
        //创建URL对象,解析路径    
        URL url = new URL(urlPath);    
        //获取连接    
        URLConnection conn = url.openConnection();    
        //获取输入流,读取获得的数据,并显示在文本框中    
        InputStream in = conn.getInputStream();    
        byte[] buf = new byte[1024];    
        int len=in.read();    
        ta.setText(new String(buf,0,len));    
    }    
    public static void main(String[] args)     
    {    
        new MyIEGUI();    
    }    
}    
附录:

几个小知识点

 InetSocketAddress对象封装的是 IP+端口, InetSocketAddress是SocketAddress的子类
  ServerSocket(int port,int backlog),其中的backlog表示队列的最大长度,即最多连入客户端的个数,即最大连接数,可以自己设定

域名解析:

    在进行访问的时候,会先在本地的hosts文件(C:\WINDOWS\system32\drivers\etc\hosts)中找对应的映射,若有,则直接返回请求,若无,则到公网的映射列表即DNS中找对应的映射,找到后,将主机名对应的IP地址返回给本机,本机通过这个IP地址找到对应的服务器


两点应用:

host映射文件中自己配置自己的IP地址和域名的映射表。

  • 可屏蔽一些恶意网址,即将对应的映射关系写入hosts中,将IP地址改为本机的回环地址,那么会直接       找到hosts,就不会将请求发送出去
  • 把经常登陆的网站ip地址配置到本地的域名映射表中,提高上网效率

            ----------- java培训、java技术博客、期待与您交流! ------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值