网络编程网络通信的介绍,UDP通信程序,TCP通信程序

一、网络编程

网络编程概述

网络编程 :

        在网络[通信协议]下,不同计算机上运行的程序,可以进行[数据传输]

 

思考:      

         A电脑中的QQ,发送消息给B电脑中的QQ。那么需要知道[哪些条件]才能发送? 

                                                                       

                   在这个故事场景下,你要怎么样才能找到这个女孩并把钱取出来?      

 第一步:

          你要先找到这家银行,也就是银行的地址

 第二步:

          找到这个女孩在几号柜台工作

第三步:

          按照银行的规则,填写取款单 

 在这个小故事中,找到这个女孩并成功取钱的要素有哪些?

银行的地址                            ---- 银行的地址

柜台号                                   ---- 通过柜台跟客户交流并处理业务

填写取款单的规则                 ----填写取款单的规则

 网咯通信的关键三要素:

IP地址:

        设备在网络中地址,是唯一的标识

端口:

        应用程序在设备中唯一的标识

协议:

        数据在[网络中传输]的规则,常见的协议有UDP协议和TCP协议

IP

IP:全称”互联网协议地址”,也称IP地址。是分配给上网设备数字标签。常见的IP分类为:ipv4和ipv6

IP域名:                                                                                                                                                

IP地址: 

 IPv4:

IPv6:

由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而IPv4的模式下[IP的总数]是有限的。

              采用128位地址长度,分成8组。

 常用命令:

ipconfig:查看本机IP地址

ping { IP地址 }:检查网络是否连通

 特殊IP地址:

127.0.0.1:是回送地址也称本地回环地址,可以代表本机的IP地址,一般用来测试使用

总结:

        1.网络通信至少需要的元素IP、端口、协议

        2.IP地址是做什么的:定位网络上设备的,有IPv4和IPv6

        3.查看本机IP地址:ipconfig 查看是否与对方互通:【ping+IP】地址;例如:192.168.10.23

加一个ipv4的分类,需要讲A-E,IP组成为:网络号 + 主机号 广域网 城域网 局域网

最大的广域网是因特网  

添加组播地址,广地址

InetAddress: 代表IP地址               

InetAddress 的使用:

  • 为了方便我们对IP地址获取和操作,Java提供了一个类[InetAddress] 供我们使用
  • InetAddress:此类表示Internet协议(IP)地址

方法名

说明

static InetAddress getByName​(String host)

确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址

String getHostName​()

获取此IP地址的主机名

String getHostAddress​()

返回文本显示中的IP地址字符串

package com.socketmodule.socketdemo1;

import java.net.InetAddress;
import java.net.UnknownHostException;

//static InetAddress getByName(String host)
//                          确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
//String getHostName()     获取此IP地址的主机名
//String getHostAddress()  返回文本显示中的IP地址字符串
public class InetadressDemo1 {
    public static void main(String[] args) throws UnknownHostException {
        //getByName(String host)确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
        InetAddress address = InetAddress.getByName("沉迷代码");
        //String getHostName()     获取此IP地址的主机名
        String hostName = address.getHostName();
        System.out.println("主机名为" + hostName);
        //String getHostAddress()  返回文本显示中的IP地址字符串
        String ip = address.getHostAddress();
        System.out.println("IP为" + ip);
    }
}

 

端口 :应用程序在设备中唯一的标识

  • 标记正在计算机设备上运行的应用程序,被规定为一个16位的二进制,范围是0~65535。

分类:

  • 周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)
  • 注册端口:1024~49151,分配给用户进程或某些应用程序。
  • 动态端口:49152~65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。

 端口号:两个字节表示的整数,它的取值范围是0~65535。

  • 其中0~1023之间的端口号用于一些知名的网络服务或者应用
  •  我们自己使用1024以上的端口号就可以了。

 注意:一个端口号只能被一个应用程序使用。

 协议:       计算机网络中连接和通信的规则被称为网络通信协议

通信协议:

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为 网络通信协议

协议:

开放式网络互连标准:OSI网络参考模型:

OSI网络参考模型:全球 网络互联标准

TCP/IP网络模型:事实上的国际标准

UDP协议:

  •         用户数据报协议(User Datagram Protocol)
  •         UDP是面向无连接通信协议。(音频,视频,普通数据会使用用UDP,因为速度快,丢失一些数据没有太大的影响)

  •   速度快,有大小限制一次最多发送64K数据不安全,易丢失数据。 

TCP协议 :

  •         传输控制协议 (Transmission Control Protocol)
  •         TCP协议是面向连接的通信协议。
  •         速度慢,没有大小限制,数据安全

 三次握手:目的是确认通信双方,收发消息都是正常没问题的 

  TCP协议:三次握手建立可靠连接 

四次挥手:目的是确保双方数据的收发已经完成,没有数据丢失  

TCP协议:四次握手断开连接

小结: 

  • 网络编程:就是可以让[两台计算机]进行[数据交互]

网络编程三要素:

  •      IP:设备在网络中唯一的标识。  
  •      端口号:应用程序在设备中唯一的标识。
  •      协议:数据在传输过程中遵守的规则。

总结:                  

通讯协议是:

  • 计算机中,连接和通信数据规则被称为网络通信协议。 

TCP通信协议的特点:

  • 它是一种面向连接的可靠的通信协议。
  • 传输前:采用“三次握手”方式建立连接,点对点的通信,所以可靠。
  • 在连接中课进行大数据量的传输。
  • 通信效率较低

UDP协议的特点是:

  • 用户数据报协议(User Datagram Protocol)
  • UDP是面向无连接不可靠传输的通信协议。
  • 速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据。  

UDP通信程序:

DatagramSocket:用于创建客户端,服务端:

DatagramPacket:创建数据包:

UDP发送数据:

         发送礼物的步骤

package com.socketmodule.socketdemo2;


import java.io.IOException;
import java.net.*;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //1.找码头
        DatagramSocket ds = new DatagramSocket();
        //2.打包礼物
        //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        String s = "送给村长老丈人的礼物";
        byte[] bytes = s.getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);


        //3.由码头发送包裹
        ds.send(dp);

        //4.付钱走羊
        ds.close();
    }
}

UDP接收数据: 

package com.socketmodule.socketdemo2;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ServerDemo {
    //注意点:
        //1.要先运行接收端,再运行发送端
        //2.如果接收端再启动之后,没有接收到数据,那么会死等(阻塞).
        //3.在接收数据的时候,需要调用一个getLength方法,表示接收到了多少字节
    public static void main(String[] args) throws IOException {
        //1.找码头     ---- 表示接收端从10000端口接收数据的.
        DatagramSocket ds = new DatagramSocket(10000);
        //2,创建一个新的箱子
        byte [] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length);
        //3.接收礼物,把礼物放到新的箱子中
        System.out.println("-----------接收前----------");
        ds.receive(dp);
        System.out.println("------------接收后---------");
        //4.从新的箱子里面获取礼物
       // byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println(new String(bytes,0,length));
        //5.拿完走羊
        ds.close();
    }
}

总结:

 

接收端可以反复接收数据 

步骤:

package com.socketmodule.socketdemo3;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        DatagramSocket ds = new DatagramSocket();
        while (true) {
            String s = sc.nextLine();
            if("886".equals(s)){
                break;
            }
            byte[] bytes = s.getBytes();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port = 10000;
            DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);

            ds.send(dp);
        }

        ds.close();
    }
}
package com.socketmodule.socketdemo3;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket(10000);

        while (true) {
            byte [] bytes = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bytes,bytes.length);

            ds.receive(dp);

            byte[] data = dp.getData();
            int length = dp.getLength();

            System.out.println(new String(data,0,length));
        }

       // ds.close();
    }
}

 UDP的三种通信方式

        单播

        组播

        广播

 

 UDP通信组播代码实现

 组播地址:224.0.0.0 ~ 239.255.255.255  

               其中224.0.0.0 ~ 224.0.0.255 为预留的组播地址

单播的发送端

  ①创建发送端的Socket对象(DatagramSocket) 

广播地址:255.255.255.255 

package com.socketmodule.socketdemo4;

import java.io.IOException;
import java.net.*;

public class ClinetDemo {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds = new DatagramSocket();

        String s = "hello 组播";
        byte[] bytes = s.getBytes();
        InetAddress address = InetAddress.getByName("224.0.1.0");
        int port = 10000;
        DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);

        ds.send(dp);

        ds.close();
    }
}
package com.socketmodule.socketdemo4;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        MulticastSocket ms = new MulticastSocket(10000);

        DatagramPacket dp = new DatagramPacket(new byte[1024],1024);


        //把当前计算机绑定一个组播地址,表示添加到这一组中.
        ms.joinGroup(InetAddress.getByName("224.0.1.0"));


        ms.receive(dp);

        byte[] data = dp.getData();
        int length = dp.getLength();
        System.out.println(new String(data,0,length));

        ms.close();
    }
}

 二、TCP通信程序:     

 

TCP通信原理    

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象。

通信之前要保证连接已经建立。

通过Socket产生IO流来进行网络通信。

TCP基于IO流,与UDP不区别(不需要整包)

 TCP发送数据步骤

发送数据的步骤:

①创建客户端的Socket对象(Socket)与指定服务端连接

        Socket​(String host, int port)

②获取输出流,写数据

        OutputStream getOutputStream​()

③释放资源

         void close​()

 TCP接收数据

接收数据的步骤:

①创建服务器端的Socket对象(ServerSocket)

②获取输入流,读数据,并把数据显示在控制台

③释放资源

接收数据的步骤 :

①创建服务器端的Socket对象(ServerSocket)

        ServerSocket​(int port)

②监听客户端连接,返回一个Socket对象

         Socket accept​()

③获取输入流,读数据,并把数据显示在控制台

         InputStream getInputStream​()

④释放资源

        void close​()

package com.socketmodule.socketdemo6;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //1,创建一个Socket对象
        Socket socket = new Socket("127.0.0.1",10000);

        //2.获取一个IO流开始写数据
        OutputStream os = socket.getOutputStream();
        os.write("hello".getBytes());

        /*while(true){

        }*/
        //3.释放资源
        os.close();
        socket.close();
    }
}
package com.socketmodule.socketdemo6;

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 {
        //1. 创建Socket对象
        ServerSocket ss = new ServerSocket(10000);
        //2. 等待客户端连接
        System.out.println(111);
        Socket accept = ss.accept();
        System.out.println(222);
        //3.获得输入流对象
        InputStream is = accept.getInputStream();
        int b;
        while((b = is.read()) != -1){
            System.out.print((char) b);
        }

        System.out.println("看看我执行了吗?");

        //4.释放资源
        is.close();
        ss.close();
    }
}

 

TCP发送数据原理 

发送数据的步骤:

 三次握手

 三次握手

四次挥手 

四次挥手

TCP单发:

 

 TCP多发:

 

 

 

 

 

TCP通信程序练习

客户端:发送数据,接收服务器反馈

服务器:接收数据,给出反馈 

 TCP通信原理

TCP通信程序练习 

客户端:将本地文件上传到服务器。接收服务器的反馈。

服务器:接收客户端上传的文件,上传完毕之后给出反馈。

 

package com.socketmodule.socketdemo7;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",35729);

        OutputStream os = socket.getOutputStream();
        os.write("hello".getBytes());
       // os.close();如果在这里关流,会导致整个socket都无法使用
        socket.shutdownOutput();//仅仅关闭输出流.并写一个结束标记,对socket没有任何影响


        /*InputStream is = socket.getInputStream();
        int b;
        while((b = is.read()) !=-1){
            System.out.println((char) b);
        }*/

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while((line = br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
        os.close();
        socket.close();
    }
}


h
e
l
l
o
看看我执行了吗?

Process finished with exit code 0

------------------------------------------


package com.socketmodule.socketdemo7;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(35729);

        Socket accept = ss.accept();

        InputStream is = accept.getInputStream();
        int b;
        while((b = is.read())!=-1){
            System.out.println((char) b);
        }

        System.out.println("看看我执行了吗?");
       /* OutputStream os = accept.getOutputStream();
        os.write("你谁啊?".getBytes());*/
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
        bw.write("你谁啊?");
        bw.newLine();
        bw.flush();

        bw.close();
        is.close();
        accept.close();
        ss.close();
    }
}

你谁啊?

Process finished with exit code 0

可见: TCP做聊天要比UDP麻烦一些

TCP通信 

package com.socketmodule.socketdemo8;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(35729);

        Socket accept = ss.accept();

        //网络中的流,从客户端读取数据的
        BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
        //本地的IO流,把数据写到本地中,实现永久化存储
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day14\\ServerDir\\copy.jpg"));

        int b;
        while((b = bis.read()) !=-1){
            bos.write(b);
        }
        //将字节输入流FileInputStream   转成     字符输入流  Fliereader

        //通过转换流
        InputStreamReader inputStreamReader = new InputStreamReader(accept.getInputStream());

        //通过缓冲输入字符流
        BufferedReader br = new BufferedReader(inputStreamReader);


        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(accept.getOutputStream());
        BufferedWriter bw = new BufferedWriter(outputStreamWriter);
        bw.write("上传成功");
        bw.newLine();
        bw.flush();

        bos.close();
        accept.close();
        ss.close();


    }
}


--------

package com.socketmodule.socketdemo8;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",35729);

        //是本地的流,用来读取本地文件的.
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day14\\ClientDir\\1.jpg"));

        //写到服务器 --- 网络中的流
        OutputStream os = socket.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(os);

        int b;
        while((b = bis.read())!=-1){
            bos.write(b);//通过网络写到服务器中
        }
        bos.flush();
        //给服务器一个结束标记,告诉服务器文件已经传输完毕
        socket.shutdownOutput();


        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line;
        while((line = br.readLine()) !=null){
            System.out.println(line);
        }
        bis.close();
        socket.close();


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值