黑马程序员——java基础知识之网络编程(二)

来源:互联网 发布:java 方法里面套方法 编辑:程序博客网 时间:2024/06/13 19:53

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
(一)网络编程的深入
1、基础知识总结:
①网络编程:主要是和IO流联系紧密,基本上有网络编程的地方,就有IO流的应用。
②当网络编程遇到一对多传输时,要利用多线程来处理
③小知识点:
游览器输入网址进行访问的时候,会先在本地的hosts文件(c:\windows\system32\drivers\ext\host)中找对应的映射。若有,则直接返回请求;若无,则到公网的映射列表即DNS中找对应的映射,找到后,将主机名对应的IP地址返回给本机,本机通过这个IP地址找到对应的服务器。
④网络编程主要要掌握UDP传输和TCP传输
UDP传输的步骤:
1)创建 UDPSocket发送服务对象:
DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。
2)发送:void send(DatagramPacket p)
3)接收:void receive(DatagramPacket p)
TCP传输的步骤:
客户端:
1)创建Socket服务,并指定要连接的主机端口。通路一建立,就会产生Socket流(包括输入流和输出流),通过方法获取
2)为了发送数据,应获取Socket中的输出流,如果要接收服务端的反馈信息,还需要获取Socket的输入流
3)通过输出流的write()方法将要发送的数据写入到流中
4)关闭Socket流资源
服务端:
1)建立服务端的Socket服务,并监听一个端口。通过ServerSocet带端口参数的构造函数
2)获取连接过来的客户对象,通过ServerSocket的accept()方法,此方法是阻塞式的,如果服务端没有连接到就会一直等待
3)客户端如果发过来数据,则服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过来的数据,并输出到指定目的地。
4)关闭服务端(可选)。一般服务端是常开的,因为在实际应用中,随时有客户端在请求连接和服务。但这里需要定时关闭客户端对象流,避免某一个客户端长时间占用服务器端。

2、网络编程的综合应用
例子1:利用网络编程实现图片上传

package cn.dhj;import java.io.*;import java.net.*;/* * 需求:网络上传图片 *客户端。1,服务端点。2,读取客户端已有的图片数据。3,通过socket 输出流将数据发给服务端。4,读取服务端反馈信息。5,关闭。 */public class UploadPic {    public static void main (String[] args) throws Exception{        Socket s = new Socket("127.0.0.1",8888);        FileInputStream fis = new FileInputStream("c:\\1.bmp");        OutputStream out = s.getOutputStream();        byte[] buf = new byte[2014];        int len = 0;        if((len=fis.read(buf))!=-1){            out.write(buf , 0 ,len);        }        s.shutdownOutput();//告诉服务端数据已经写完,也就是做一个标记        InputStream In = s.getInputStream();        byte[] bufIn = new byte[2014];        int read = In.read(bufIn);        System.out.println(new String(bufIn,0,read));    }}class UploadPicServer {    public static void main (String[] args) throws Exception{    ServerSocket ss = new ServerSocket(8888);    Socket s =ss.accept();    InputStream Inc = s.getInputStream();    FileOutputStream outc = new FileOutputStream("server.bmp");    byte[] buf = new byte[2014];    int len = 0;    while((len=Inc.read(buf))!=-1){        outc.write(buf,0,len);    }    OutputStream out = s.getOutputStream();    out.write("上传成功".getBytes());    Inc.close();    ss.close();    s.close();    }   }

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

package cn.dhj;import java.io.*;import java.net.*;/* * /*服务端那么为了可以让多个客户端同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。如何定义线程呢?只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。*/public class TCPserver {    public static void main (String[] args) throws Exception{        ServerSocket ss = new ServerSocket(8888);         while(true){            Socket s = ss.accept();            //启动新线程            new Thread(new PicThrowd(s)).start();        }    }}class PicThrowd implements Runnable{    private Socket s;    public PicThrowd(Socket s) {        super();        this.s = s;    }    public void run(){        String ip = s.getInetAddress().getHostAddress();        int count = 1;        try{            System.out.println(ip+"......connected");            InputStream Inc = s.getInputStream();            File dir = new File("d:\\pic");            File file = new File(dir,ip+"("+count+")"+".jpg");            FileOutputStream outc = new FileOutputStream(file);            byte[] buf = new byte[2014];            int len = 0;            while((len=Inc.read(buf))!=-1){                outc.write(buf,0,len);            }            OutputStream out = s.getOutputStream();            out.write("上传成功".getBytes());            Inc.close();            outc.close();            s.close();        }catch(Exception e){            throw new RuntimeException(ip+"上传失败");        }    }}/*客户端。1,服务端点。2,读取客户端已有的图片数据。3,通过socket 输出流将数据发给服务端。4,读取服务端反馈信息。5,关闭。 */class TCPclient{    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("127.0.0.1",8888);        FileInputStream fIn = new FileInputStream(file);        OutputStream out = s.getOutputStream();        byte[] buf = new byte[2014];        int line = 0;        while((line = fIn.read(buf))!=-1){            out.write(buf, 0, line);        }        //告诉服务器已经写完了        s.shutdownInput();        //接受服务器发送的信息        InputStream Inp = s.getInputStream();        byte[] bufin = new byte[2014];        int sum = Inp.read(bufin);        System.out.println(new String(bufin,0,sum));        fIn.close();        s.close();    }}

例子3:TCP客户端并发登陆

package cn.dhj;/*客户端通过键盘录入用户名。服务端对这个用户名进行校验。如果该用户存在,在服务端显示xxx,已登陆。并在客户端显示 xxx,欢迎光临。如果该用户存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。最多就登录三次。*/import java.io.*;import java.net.*;//客户端public class UerserLoderClient{    public static void main (String[] args) throws Exception{        Socket s = new Socket("127.0.0.1",8888);        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));        PrintWriter out = new PrintWriter(s.getOutputStream(),true);        BufferedReader bout = new BufferedReader(new InputStreamReader(s.getInputStream()));        for (int i=1;i<=3;i++){            String line = bufr.readLine();            if (line == null)                break;            out.write(line);            String info = bout.readLine();            System.out.println("info"+info);            if(info.contains("欢迎"))                break;        }    }}//服务端class UererLoaderServer{    public static void main(String[] args) throws Exception{        ServerSocket ss = new ServerSocket(8888);           while(true){            Socket s = ss.accept();            new Thread(new ThreadServer(s)).start();        }    }}//利用多线程实现并发登录  class ThreadServer implements Runnable{    private Socket s;    public ThreadServer(Socket s) {        super();        this.s = s;    }    public void run(){        String ip = s.getInetAddress().getHostAddress();         System.out.println(ip+"....connected");        try{            for(int i=1;i<=3;i++){            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));            String name = bufIn.readLine();            if(name==null)                break;            BufferedReader bufr = new BufferedReader(new FileReader("user.text"));            PrintWriter out = new PrintWriter(s.getOutputStream());            String line = null;            boolean flag = false;            while((line=bufr.readLine())!=null){                if(line.equals(name)){                    flag = true;                    break;                }            }            if(flag = true){                System.out.println(name+"已登入");                out.write(name+"欢迎登入");            }else{                System.out.println(name+"尝试登入");                out.write(name+"用户名不存在");            }            s.close();            }            }catch(Exception e){                throw new RuntimeException(ip+"校验失败");            }           }}

例子4、客户端和游览器的演示
总结:游览器是一个客户端
java编译是在传输层和网际层处理的,会接受到全部的消息,包含了头消息。而浏览器处于应用层,已将发送来的头消息去除,只留下了主体信息。

import java.io.*;  import java.net.*;  //服务器  class  ServerDemo  {      public static void main(String[] args)throws Exception       {          //创建服务,监听端口          ServerSocket ss=new ServerSocket(10000);          //获取客户端          Socket s=ss.accept();          //显示ip          String ip=s.getInetAddress().getHostAddress();          System.out.println(ip);          //读取客户端读取流数据          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);///true一定要记得写          out.println("<font color='red' size='7'>客户端你好!</font>");          s.close();//关流          ss.close();      }  }  

例子5、
自定义浏览器,显示网页信息

/* 自定义浏览器,显示网页信息 */  import java.io.*;  import java.awt.*;  import java.awt.event.*;  import java.net.*;  class MyIEGUIDemo  {      //定义所需组件引用      private Frame f;      private Button but,bok;      private TextField tf;      private TextArea ta;      //构造函数      MyIEGUIDemo()      {          init();      }      //窗体基本设置于功能实现      public void init()      {          //组件实例化          f=new Frame("我的Window");          but=new Button("跳转");          tf=new TextField(50);          ta=new TextArea(25,60);          //基本设置          f.setBounds(300,150,500,500);          f.setLayout(new FlowLayout());          //添加组件          f.add(tf);          f.add(but);          f.add(ta);          //窗体事件          myEvent();          //窗体显示          f.setVisible(true);      }      //注册事件      public void myEvent()      {          //窗体关闭功能          f.addWindowListener(new WindowAdapter()          {              public void windowClosing(WindowEvent e)              {                  System.exit(0);              }          });          //“跳转”按钮事件          but.addActionListener(new ActionListener()          {              public void actionPerformed(ActionEvent e)              {                  showFile();//显示网页内容在文本区中              }          });          //文本框键盘事件          tf.addKeyListener(new KeyAdapter()          {              public void keyPressed(KeyEvent e)              {                  //如果键盘按下Enter键,就将网页内容显示在文本区中                  if(e.getKeyCode()==KeyEvent.VK_ENTER)                      showFile();              }          });      }      //显示网页内容          private void showFile()          {              ta.setText("");              String path=tf.getText();//获取输入的路径              try              {                  //封装地址对象  URL url =new URL(path);  连接网页服务器                  URLConnection conn=url.openConnection();                  //读取流,用于读取服务器返回数据                  InputStream in=conn.getInputStream();                  byte[] buf=new byte[1024*1024];                  int len=in.read(buf);                  //将数据显示在文本区中                  ta.append(new String(buf,0,len));              }              catch (Exception e)              {                  throw new RuntimeException("连接"+path+"网站失败");              }          }      public static void main(String[] args)       {          //运行窗体          new MyIEGUIDemo();      }  }  

自定义游览器知识储备和总结:
了解URL和URLConnection:
1、URL:
URI:范围更大,条形码也包含于此范围
URL:范围较小,即域名
方法:
1)构造函数:URL(String protocol,String host,int port,String file);//根据指定 protocol、host、port号和 file 创建 URL对象。
2)String getProtocol();//获取协议名称
3)String getHost();//获取主机名
4)int getPort();//获取端口号
5)String getFile();//获取URL文件名
6)String getPath();//获取此URL的路径部分
7)String getQuery();//获取此URL的查询部,客户端传输的特定
2、URLConnection
方法:
1)URLConnection openConnection();//用URL调用此方法,返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
2)InputStream getInputStream();//获取输入流
3)OutputStream getOutputStream();//获取输出流

0 0
原创粉丝点击