网络编程

来源:互联网 发布:js选择器innerhtml 编辑:程序博客网 时间:2024/06/05 20:15

这里写图片描述

网络编程三要素

网络编程三要素:    A:IP地址    B:端口    C:协议举例:    我想和林青霞说话了。肿么办?    A:我要找到林青霞。    B:对她说话,要对耳朵说。    C:我说什么呢?"I Love You"      但是,她没学过英语,听不懂。      我没必要说英语,说汉语就可以了:我爱你IP地址:    网络中计算机的唯一标识。    计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。    但是呢,我们配置的IP地址确不是二进制的,为什么呢?        IP:192.168.1.100        换算:11000000 10101000 00000001 01100100    假如真是:11000000 10101000 00000001 01100100的话。    我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。    所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示:        "点分十进制"    IP地址的组成:网络号段+主机号段        A类:第一号段为网络号段+后三段的主机号段            一个网络号:256*256*256 = 16777216        B类:前二号段为网络号段+后二段的主机号段            一个网络号:256*256 = 65536        C类:前三号段为网络号段+后一段的主机号段            一个网络号:256    IP地址的分类:        A类  1.0.0.1---127.255.255.254   (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)                           (2)127.X.X.X是保留地址,用做循环测试用的。        B类  128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。        C类  192.0.0.1---223.255.255.254 192.168.X.X是私有地址        D类  224.0.0.1---239.255.255.254             E类  240.0.0.1---247.255.255.254    两个DOS命令:        ipconfig 查看本机ip地址        ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题    特殊的IP地址:        127.0.0.1 回环地址(表示本机)        x.x.x.255 广播地址        x.x.x.0 网络地址端口号:    正在运行的程序的标识。    有效端口:0~65535,其中0~1024系统使用或保留端口。协议:    通信的规则    UDP:        把数据打包        数据有限制        不建立连接        速度快        不可靠    TCP:        建立连接通道        数据无限制        速度慢        可靠    举例:        UDP:发短信        TCP:打电话

IP

  如果一个类没有构造方法:  A:成员全部是静态的(Math,Arrays,Collections)  B:单例设计模式(Runtime)  C:类中有静态方法返回该类的对象(InetAddress)        class Demo {            private Demo(){}            public static Demo getXxx() {                return new Demo();            }        }  看InetAddress的成员方法:  public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到IP地址对象  public String getHostName():获取主机名  public String getHostAddress():获取IP地址
package cn.itcast_01;import java.net.InetAddress;import java.net.UnknownHostException;public class InetAddressDemo {    public static void main(String[] args) throws UnknownHostException {        // public static InetAddress getByName(String host)        // InetAddress address = InetAddress.getByName("liuyi");        // InetAddress address = InetAddress.getByName("192.168.12.92");        InetAddress address = InetAddress.getByName("192.168.12.63");        // 获取两个东西:主机名,IP地址        // public String getHostName()        String name = address.getHostName();        // public String getHostAddress()        String ip = address.getHostAddress();        System.out.println(name + "---" + ip);    }}

Socket

这里写图片描述

UDP

  UDP协议发送数据:      A:创建发送端Socket对象          public DatagramSocket()      B:创建数据,并把数据打包          DatagramPacket(byte[] buf, int length, InetAddress address, int port)      C:调用Socket对象的发送方法发送数据包          public void send(DatagramPacket p)      D:释放资源          close()
package cn.itcast_02;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class SendDemo {    public static void main(String[] args) throws IOException {        // 创建发送端Socket对象        // DatagramSocket()        DatagramSocket ds = new DatagramSocket();        // 创建数据,并把数据打包        // DatagramPacket(byte[] buf, int length, InetAddress address, int port)        // 创建数据        byte[] bys = "hello,udp,我来了".getBytes();        // 长度        int length = bys.length;        // IP地址对象        InetAddress address = InetAddress.getByName("192.168.12.92");        // 端口        int port = 10086;        DatagramPacket dp = new DatagramPacket(bys, length, address, port);        // 调用Socket对象的发送方法发送数据包        // public void send(DatagramPacket p)        ds.send(dp);        // 释放资源        ds.close();    }}
  UDP协议接收数据:      A:创建接收端Socket对象          public DatagramSocket(int port)      B:创建一个数据包(接收容器)          DatagramPacket(byte[] buf, int length)      C:调用Socket对象的接收方法接收数据          public void receive(DatagramPacket p)      D:解析数据包,并显示在控制台          public InetAddress getAddress()          public byte[] getData():获取数据缓冲区          public int getLength():获取数据的实际长度      E:释放资源          close()
package cn.itcast_02;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class ReceiveDemo {    public static void main(String[] args) throws IOException {        // 创建接收端Socket对象        // DatagramSocket(int port)        DatagramSocket ds = new DatagramSocket(10086);        // 创建一个数据包(接收容器)        // DatagramPacket(byte[] buf, int length)        byte[] bys = new byte[1024];        int length = bys.length;        DatagramPacket dp = new DatagramPacket(bys, length);        // 调用Socket对象的接收方法接收数据        // public void receive(DatagramPacket p)        ds.receive(dp); // 阻塞式        // 解析数据包,并显示在控制台        // 获取对方的ip        // public InetAddress getAddress()        InetAddress address = dp.getAddress();        String ip = address.getHostAddress();        // public byte[] getData():获取数据缓冲区        // public int getLength():获取数据的实际长度        byte[] bys2 = dp.getData();        int len = dp.getLength();        String s = new String(bys2, 0, len);        System.out.println(ip + "传递的数据是:" + s);        // 释放资源        ds.close();    }}

与多线程结合

package cn.itcast_05;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class ReceiveThread implements Runnable {    private DatagramSocket ds;    public ReceiveThread(DatagramSocket ds) {        this.ds = ds;    }    @Override    public void run() {        try {            while (true) {                // 创建一个包裹                byte[] bys = new byte[1024];                DatagramPacket dp = new DatagramPacket(bys, bys.length);                // 接收数据                ds.receive(dp);                // 解析数据                String ip = dp.getAddress().getHostAddress();                String s = new String(dp.getData(), 0, dp.getLength());                System.out.println("from " + ip + " data is : " + s);            }        } catch (IOException e) {            e.printStackTrace();        }    }}
package cn.itcast_05;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class SendThread implements Runnable {    private DatagramSocket ds;    public SendThread(DatagramSocket ds) {        this.ds = ds;    }    @Override    public void run() {        try {            // 封装键盘录入数据            BufferedReader br = new BufferedReader(new InputStreamReader(                    System.in));            String line = null;            while ((line = br.readLine()) != null) {                if ("886".equals(line)) {                    break;                }                // 创建数据并打包                byte[] bys = line.getBytes();                // DatagramPacket dp = new DatagramPacket(bys, bys.length,                // InetAddress.getByName("192.168.12.92"), 12345);                DatagramPacket dp = new DatagramPacket(bys, bys.length,                        InetAddress.getByName("192.168.12.255"), 12306);                // 发送数据                ds.send(dp);            }            // 释放资源            ds.close();        } catch (IOException e) {            e.printStackTrace();        }    }}
package cn.itcast_05;import java.io.IOException;import java.net.DatagramSocket;/* * 通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了 */public class ChatRoom {    public static void main(String[] args) throws IOException {        DatagramSocket dsSend = new DatagramSocket();        DatagramSocket dsReceive = new DatagramSocket(12306);        SendThread st = new SendThread(dsSend);        ReceiveThread rt = new ReceiveThread(dsReceive);        Thread t1 = new Thread(st);        Thread t2 = new Thread(rt);        t1.start();        t2.start();    }}

TCP

这里写图片描述

  TCP协议发送数据:      A:创建发送端的Socket对象          Socket(InetAddress address, int port)          Socket(String host, int port)            这一步如果成功,就说明连接已经建立成功了。      B:获取输出流,写数据          public OutputStream getOutputStream()      C:释放资源  连接被拒绝。TCP协议一定要先看服务器。  java.net.ConnectException: Connection refused: connect
package cn.itcast_06;import java.io.IOException;import java.io.OutputStream;import java.net.Socket;public class ClientDemo {    public static void main(String[] args) throws IOException {        // 创建发送端的Socket对象        // Socket(InetAddress address, int port)        // Socket(String host, int port)        // Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);        Socket s = new Socket("192.168.12.92", 8888);        // 获取输出流,写数据        // public OutputStream getOutputStream()        OutputStream os = s.getOutputStream();        os.write("hello,tcp,我来了".getBytes());        // 释放资源        s.close();    }}
  TCP协议接收数据:  A:创建接收端的Socket对象      ServerSocket(int port)  B:监听客户端连接。返回一个对应的Socket对象      public Socket accept()  C:获取输入流,读取数据显示在控制台  D:释放资源
package cn.itcast_06;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {    public static void main(String[] args) throws IOException {        // 创建接收端的Socket对象        // ServerSocket(int port)        ServerSocket ss = new ServerSocket(8888);        // 监听客户端连接。返回一个对应的Socket对象        // public Socket accept()        Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。        // 获取输入流,读取数据显示在控制台        InputStream is = s.getInputStream();        byte[] bys = new byte[1024];        int len = is.read(bys); // 阻塞式方法        String str = new String(bys, 0, len);        String ip = s.getInetAddress().getHostAddress();        System.out.println(ip + "---" + str);        // 释放资源        s.close();        // ss.close(); //这个不应该关闭    }}

带反馈的

package cn.itcast_07;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class ServerDemo {    public static void main(String[] args) throws IOException {        // 创建服务器Socket对象        ServerSocket ss = new ServerSocket(9999);        // 监听客户端的连接        Socket s = ss.accept(); // 阻塞        // 获取输入流        InputStream is = s.getInputStream();        byte[] bys = new byte[1024];        int len = is.read(bys); // 阻塞        String server = new String(bys, 0, len);        System.out.println("server:" + server);        // 获取输出流        OutputStream os = s.getOutputStream();        os.write("数据已经收到".getBytes());        // 释放资源        s.close();        // ss.close();    }}
package cn.itcast_07;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;public class ClientDemo {    public static void main(String[] args) throws IOException {        // 创建客户端Socket对象        Socket s = new Socket("192.168.12.92", 9999);        // 获取输出流        OutputStream os = s.getOutputStream();        os.write("今天天气很好,适合睡觉".getBytes());        // 获取输入流        InputStream is = s.getInputStream();        byte[] bys = new byte[1024];        int len = is.read(bys);// 阻塞        String client = new String(bys, 0, len);        System.out.println("client:" + client);        // 释放资源        s.close();    }}

终止功能

  按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?  读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。  所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。  如何解决呢?  A:在多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。        这样做可以解决问题,但是不好。  B:Socket对象提供了一种解决方案        public void shutdownOutput()
package cn.itcast_12;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;public class UploadClient {    public static void main(String[] args) throws IOException {        // 创建客户端Socket对象        Socket s = new Socket("192.168.12.92", 11111);        // 封装文本文件        BufferedReader br = new BufferedReader(new FileReader(                "InetAddressDemo.java"));        // 封装通道内流        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(                s.getOutputStream()));        String line = null;        while ((line = br.readLine()) != null) { // 阻塞            bw.write(line);            bw.newLine();            bw.flush();        }        //自定义一个结束标记//      bw.write("over");//      bw.newLine();//      bw.flush();        //Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了        s.shutdownOutput();        // 接收反馈        BufferedReader brClient = new BufferedReader(new InputStreamReader(                s.getInputStream()));        String client = brClient.readLine(); // 阻塞        System.out.println(client);        // 释放资源        br.close();        s.close();    }}
package cn.itcast_12;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;public class UploadServer {    public static void main(String[] args) throws IOException {        // 创建服务器端的Socket对象        ServerSocket ss = new ServerSocket(11111);        // 监听客户端连接        Socket s = ss.accept();// 阻塞        // 封装通道内的流        BufferedReader br = new BufferedReader(new InputStreamReader(                s.getInputStream()));        // 封装文本文件        BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));        String line = null;        while ((line = br.readLine()) != null) { // 阻塞        // if("over".equals(line)){        // break;        // }            bw.write(line);            bw.newLine();            bw.flush();        }        // 给出反馈        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(                s.getOutputStream()));        bwServer.write("文件上传成功");        bwServer.newLine();        bwServer.flush();        // 释放资源        bw.close();        s.close();    }}

多客户端同时运行

package cn.itcast_15;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;public class UserThread implements Runnable {    private Socket s;    public UserThread(Socket s) {        this.s = s;    }    @Override    public void run() {        try {            // 封装通道内的流            BufferedReader br = new BufferedReader(new InputStreamReader(                    s.getInputStream()));            // 封装文本文件            // BufferedWriter bw = new BufferedWriter(new            // FileWriter("Copy.java"));            // 为了防止名称冲突            String newName = System.currentTimeMillis() + ".java";            BufferedWriter bw = new BufferedWriter(new FileWriter(newName));            String line = null;            while ((line = br.readLine()) != null) { // 阻塞                bw.write(line);                bw.newLine();                bw.flush();            }            // 给出反馈            BufferedWriter bwServer = new BufferedWriter(                    new OutputStreamWriter(s.getOutputStream()));            bwServer.write("文件上传成功");            bwServer.newLine();            bwServer.flush();            // 释放资源            bw.close();            s.close();        } catch (IOException e) {            e.printStackTrace();        }    }}
package cn.itcast_15;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class UploadServer {    public static void main(String[] args) throws IOException {        // 创建服务器Socket对象        ServerSocket ss = new ServerSocket(11111);        while (true) {            Socket s = ss.accept();            new Thread(new UserThread(s)).start();        }    }}
package cn.itcast_15;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;public class UploadClient {    public static void main(String[] args) throws IOException {        // 创建客户端Socket对象        Socket s = new Socket("192.168.12.92", 11111);        // 封装文本文件        // BufferedReader br = new BufferedReader(new FileReader(        // "InetAddressDemo.java"));        BufferedReader br = new BufferedReader(new FileReader(                "ReceiveDemo.java"));        // 封装通道内流        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(                s.getOutputStream()));        String line = null;        while ((line = br.readLine()) != null) { // 阻塞            bw.write(line);            bw.newLine();            bw.flush();        }        // Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了        s.shutdownOutput();        // 接收反馈        BufferedReader brClient = new BufferedReader(new InputStreamReader(                s.getInputStream()));        String client = brClient.readLine(); // 阻塞        System.out.println(client);        // 释放资源        br.close();        s.close();    }}
0 0