zoukankan      html  css  js  c++  java
  • Java网络编程

    1,IP地址和InetAddress

     

     

    IP地址是互联网上每台计算机都有的自己的标记,IP地址分为5类,A类保留给政府,B类给中等规模的公司,C类给任何需要的人,D类用于组播,E类用于实验.

    A类  1.0.0.1-126.255.255.254  B类  128.0.0.1-191.255.255.254   C类  192.0.0.1-223.255.255.254  D类 244.0.0.1-239.255.255.254

    E类 240.0.0.1-255.255.255.254

    在以后开发的时候,经常使用的127.0.0.1表示的是本机的IP地址

    InetAddress

    该类主要表示的是IP地址,有两个子类,Inet4Address和Inet6Address

    该类没有构造函数,但是有提供了静态的方法去获得该类的对象

    1

    我们去获取本家的IP地址等一些信息的时候,先通过该类的静态方法去得到一个InetAddress的对象,有了对象后,通过该类中的各种方法,去获取相信的信息,比如需要打印出IP地址的话,使用的肯定是返回值为String的方法.

    package cn.wjd.ip;
    
    import java.net.InetAddress;
    
    public class IPDemo {
        public static void main(String[] args) throws Exception {
            //获取本地地址IP对象
            InetAddress ip = InetAddress.getLocalHost();
            ip = InetAddress.getByName("www.baidu.com");//本地DNS   hosts
            System.out.println(ip.getHostAddress());
            System.out.println(ip.getHostName());
        }
    
    }

    2,UDP程序设计

    UDP是不可靠的连接协议,这种协议在各种聊天工具中被广泛的使用,在java中使用DatagramSocket来完成对信息的发送,使用DatagramPacket来包装一条需要发送的信息

    package cn.net;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.LineNumberReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class Send implements Runnable {
        // 创建UDP的Socket流对象
        private DatagramSocket ds = null;
    
        public Send(DatagramSocket ds) {
            super();
            this.ds = ds;
        }
    
        public void run() {
            try {
                BufferedReader bufr = new BufferedReader(new InputStreamReader(
                        System.in));
                String line = null;
                while ((line = bufr.readLine()) != null) {
                    byte[] buf = line.getBytes();
                    DatagramPacket dp = new DatagramPacket(buf, buf.length,
                            InetAddress.getByName("wjd"), 9999);
                    ds.send(dp);
                    if("88".equals(line))
                        break;
                }
                ds.close();
            } catch (Exception e) {
    
                e.printStackTrace();
            }
        }
    }
    package cn.net;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    public class Rece implements Runnable{
        private DatagramSocket ds = null;
        
        public Rece(DatagramSocket ds) {
            super();
            this.ds = ds;
        }
    
        public void run(){
            try {
            while(true){
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf,buf.length);
                    ds.receive(dp);
                    int port = dp.getPort();
                    String ip = dp.getAddress().getHostName();
                    String text = new String(dp.getData(),0,dp.getLength());
                    System.out.println("ip:"+ip+" port:"+port+" text:"+text);
                    if("88".equals(text)){
                        System.out.println("退出聊天!!");
                    }
                    //ds.close();
                }
            
            }catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    package cn.net;
    
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class Chat {
        public static void main(String[] args) throws SocketException {
            DatagramSocket rece = new DatagramSocket(9999);
            DatagramSocket send = new DatagramSocket();
            Send s = new Send(send);
            Rece r = new Rece(rece);
            Thread t1 = new Thread(s);
            Thread t2 = new Thread(r);
            t1.start();
            t2.start();
        }
    
    }

    创建一个UDP的客户端,用来接受数据

    发送端: 1,创建UDP的socket流,datagramsocket

              2,创建键盘输入流,system.in

              3,将需要的信息通过datagrampacket进行封装,封装的内容包括数据包的大小byte数组,长度,IP地址,发送信息的时候,必须要明确端口号

              4,通过UDP的socket流来发送数据包

              5,关闭UDP的socket流

    接收端:1,创建UDP的socket流,datagramsocket

             2,创建一个byte数组,用UDP的socket流来接受数据包

             3,通过接受到的数据包,获取数据包的中内容,包括里面的内容,IP地址,端口号等

    注意点:在发送端方面,对数据包进行实例化的时候,需要在其构造方法中明确,数据的内容(byte数组),数据的长度,要发送的目标地址,发送的端口,这个端口号是在datagrampacket,封装数据包的构造函数的时候明确的.

    在接收端方面,创建数据包的接受对象,和UDP的socket流对象(在这个流对象中要明确我们在发送信息的时候,需要在哪个端口监听,与发送端的端口号要一致)

     

    3,URL和URLConnection

    URL是统一资源定位符,可以使用此类找到互联网上的资源(比如一个简单的网页)

    URLConnection是封装访问远程网络资源一般方法的类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性

    package cn.wjd.ie_server;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    public class URLDemo {
        public static void main(String[] args) throws IOException {
            String url_str = "http://127.0.0.1:8080/myweb/reg.html";
            URL url = new URL(url_str);
            //InputStream in = url.openStream();
            //获取URL对象的url连接器对象,将连接封装成对象:java中内置可以解析具体协议的的对象+socket
            URLConnection conn = url.openConnection();
            System.out.println(conn.toString());
            //sun.net.www.protocol.http.HttpURLConnection:http://127.0.0.1:8080/myweb/reg.html
            byte[] buf = new byte[2588];
        //    int len = in.read(buf);
        //    String test = new String(buf,0,len);
        //    System.out.println(test);
        }
    
    }

    4,TCP程序设计

    在Java中,使用Socket来完成TCP程序的开发,使用此类可以方便的建立可靠的,双向的,持续的,点对点的通信连接.

    在客户端当面,我们可以直接创建Socket对象,在服务端,先创建ServerSocket对象,通过该对象的accept方法,来获取到Socket,也就是说在整个TCP的信息的流通中,都是通过这个socket流来完成的.

    ServerSocket类与Socket类

    ServerSocket类是主要用于服务端程序的开发,用于接受客户端的连接请求,在服务器端每次运行时都是使用accept()方法等待客户端连接,此方法执行后,服务器端将进入阻塞状态,直到客户端连接之后程序才可以向下执行,此方法的返回值是Socket,每一个Socket都便是一个客户端对象.

    大白话理解的话,在TCP客户端和服务端进行数据通讯的时候,存在的是一个Socket流,这个流首先是由客户端通过outputstream的形式发出的流通的管道中,然后到了服务端这边,我们得先ServerSocket对象,然后通过该实例化对象,来拿到管道中的Socket流,然后在通过inputstream来获取到这个管道中的信息.

    但是在最后运行的时候,由于accept这个方法是阻塞的,我们得先运行服务端,再运行客户端这样才能顺利的进行通讯.

    编写TCP客户端的步骤

    1,创建Socket对象,同时指定要连接服务器的主机名称和连接端口号

    2,创建Socket输出流,将需要发送的数据变成字节的形式(在Socket流中走的数据都是以字节的形式存在的),放在socket流中,在客户端中,发送信息,客户端->服务器端(out)     在服务器端反馈信息   服务器端->客户端(in)

    3,关闭socket流

    package cn.tcp;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Client {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket s = new Socket(InetAddress.getByName("wjd"),8767);
            OutputStream out = s.getOutputStream();
            out.write("我是来发送数据的!!".getBytes());
            s.close();
        }
    }

    编写TCP服务端的步骤

    1,创建ServerSocket对象,在该对象的构造方法中,必须要明确客户端那边的端口号

    2,使用accept()方法,来获取Socket流.

    3,由于客户端那边已经out信息给服务端了,那么我们在服务端就要in信息出来,  搞了inoutstream对象,这样在TCP通信中就形成了一个完整的Socket流,有输出有输入

    4,对in进行读取操作,读出客户端发给服务端的信息,然后将字节变成String,进行输出

    5,关闭s流和ss流

    package cn.tcp;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(8767);
            Socket s = ss.accept();
            InputStream in = s.getInputStream();
            String ip = s.getInetAddress().getHostAddress();
            int len = 0;
            byte[] buf = new byte[1024];
            len = in.read(buf);
            String str = new String(buf,0,len);
            System.out.println("接受客户端的内容:"+str+" ip:"+ip);
            ss.close();
            s.close();
        }
    
    }

     

    客户端和服务端进行数据交互,当在客户端输入小写字母的时候,在服务端进行处理,变成大写字母,反馈给客户端进行输出

    客户端:  客户端->服务端发送信息 源键盘  目的socket的输出流(使用printWriter)

              服务端->客户端反馈信息  socket输入流,来接受服务端处理好的信息,并将处理好的信息打印到控制台上去

    服务端:  接受客户端的信息  socket输入流,     服务端->客户端返回处理好的信息  printWriter流

    readLine()是根据判断是否有换行来结束,所以在printwriter进行输出的时候,一定是println,这样才会有换行的标记

    printwriter进行输出的时候,一定要进行刷新的动作,如果不刷新的话,数据只会进入printwriter流中,而不会进入socket流

    package cn.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TransServer {
        public static void main(String[] args) throws IOException {
            //获取socket流
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();
            System.out.println(s.getInetAddress().getHostAddress());
            //获取socket输出流  客户端->服务端的信息
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
            
            //获取socket输出流  服务端->客户端 信息的反馈
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            //进行读写操作
            String line;
            while((line=bufIn.readLine())!=null){
                System.out.println(line);
                //将字母小写变成大写
                String strUpper = line.toUpperCase();
                //通过Socket流,服务端->客户端信息的反馈,将大写字母给到客户端去显示
                out.println(strUpper);
            }
        }
    
    }
    package cn.tcp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TransClient {
        public static void main(String[] args) throws UnknownHostException, IOException {
            //创建Socket流
            Socket s = new Socket(InetAddress.getByName("wjd"),10000);
            //创建源 键盘输入
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            //创建socket输出流  客户端->服务端
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            
            //创建socket流,用来接受服务端的反馈信息
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
            //进行键盘读写操作
            String line;
            while((line=bufr.readLine())!=null){
                if("over".equals(line))
                    break;
                out.println(line);
                //读取服务端返回的信息,该信息已经在服务端,把小写字母变成大写字母了.
                String strUpper = bufIn.readLine();
                System.out.println(strUpper);
            }
            s.close();//在socket流中植入了结束的标记
        }
    
    }

    TCP从客户端上上传图片或者文本文件到服务器

    在Java IO中,到需要操作到文本文件的时候,源和目的的明确,使用到的是fileinputstream和fileoutputstream

    操作图片.歌曲这些字节的时候,源和目的的明确,使用到的是filewriter和filereader

    由于客户端和服务端之间有数据的交互,所以以后碰到该类问题的时候,我们在服务端完成数据传输动作的时候,必须要告诉服务端,这个时候客户端已经把事情办完了,不告诉服务端的话,服务端会一直处于等待状态,服务端的程序就不会结束,这个时候就得用到socket流中的一个方法1

    服务器在操作文本数据,写入数据的时候,由于这边使用到了缓冲区,那么在写完数据的时候,必须要做一次刷新缓冲区的这个动作.

    以后操作文本文件,这类的字符文件的时候,需要输出的话,可以优先考虑到IO中的打印流,打印流是输出信息最方便的类.

    package cn.tcp;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class UploadTXTClient {
        public static void main(String[] args) throws UnknownHostException, IOException {
            //创建socket流,明确地址和端口号
            Socket s = new Socket(InetAddress.getByName("wjd"),10002);
            //明确上传文件的源文件的地址
            BufferedReader bufr = new BufferedReader(new FileReader("各种需求.txt"));
            //创建socket输出流 客户端->服务端
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            String lin = null;
            //读取上传文件的(源文件)的信息,然后再通过打印流,就数据进入到socket流中去
            while((lin=bufr.readLine())!=null){
                out.println(lin);    
            }
            //告诉服务器端,客户端这边的TXT文件的数据已经读完了
            s.shutdownOutput();
            //拿到服务端到客户端反馈的信息
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String str = bufIn.readLine();
            System.out.println(str);
            bufr.close();
            s.close();
        }
    
    }
    package cn.tcp;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class UploadTXTServer {
        public static void main(String[] args) throws IOException {
            //得到socket流
            ServerSocket ss = new ServerSocket(10002);
            Socket s = ss.accept();
            System.out.println(s.getLocalAddress().getHostAddress()+"connection...");
            //确定需要上传后的文件的名称和目的
            BufferedWriter bufw = new BufferedWriter(new FileWriter("load.txt"));
            //得到socket中的输入流
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String lin = null;
            //拿到socket流中的数据,进行读取,并写入指定的文件
            while((lin=bufIn.readLine())!=null){
                bufw.write(lin);
                bufw.newLine();
                //由于使用了缓冲区,这边必要要刷新,才能将数据写入到目的文件中去
                bufw.flush();
            }
            
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            out.println("OK!!");
            ss.close();
            s.close();
        }
    
    }
    package cn.tcp;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class LoadMP3Clinet {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket s = new Socket(InetAddress.getByName("wjd"),10003);
            FileInputStream fis = new FileInputStream("1.mp3");
            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[] serverBuf = new byte[1024];
            int serverLen = 0;
            while((serverLen=in.read(serverBuf))!=-1){
                String str = new String(serverBuf,0,serverLen);
                System.out.println(str);
            }
        }
    
    }
    package cn.tcp;
    
    import java.io.FileOutputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class LoadMP3Server {
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(10003);
            Socket s = ss.accept();
            System.out.println(s.getInetAddress().getHostName()+"以连接上....");
            FileOutputStream fos = new FileOutputStream("server.mp3");
            InputStream in = s.getInputStream();
            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());
            ss.close();
            s.close();
        }
    
    }
  • 相关阅读:
    第二周教学设计反思
    uni-app,一套代码应用在多个平台
    新CMS
    学习js
    关于数据库
    自己写的一段jquery实现当滚动条滑动到某个位置实现向中间移动
    js平滑滚动到顶部、底部、指定地方
    统一一个帝国中搜索页面的模板
    帝国CMS的总结
    回到顶部的功能
  • 原文地址:https://www.cnblogs.com/driverwjd/p/3872470.html
Copyright © 2011-2022 走看看