网络编程初学

一 网络编程相关基础概念

1.1网络通讯

两台设备之间通过网络实现数据传输

网络通信:将数据通过网络从一台设备传输到另一台设备

1.2网络

概念:利用通信线路和通信设备,将地理位置不同的、功能独立的多台计算机互连起来,以功能完善的网络软件来实现资源共享和信息传递,就构成了计算机网络系统

根据网络的覆盖范围不同,对网络进行分类:

局域网:覆盖范围最小 仅仅覆盖一个教室或一个学校(校园网) 

城域网:覆盖范围较大 可以覆盖一个城市

广域网:覆盖范围最大 可以覆盖全国 甚至全球 万维网是广域网的代表

1.3IP地址

主机的身份证号 用于辨别

1.3.1.概念IP地址(Internet Protocol Address),全称为网际协议地址,是一种在Internet上的给主机编址的方式。它是IP协议提供的一种统一的地址格式用于唯一标识网络中的每台计算机/主机

1.3.2.查看ip地址的方式:在dos下输入 ipconfig即可获得   本机192.168.43.xx

1.3.3.ip地址的表示形式:点分十进制 xx.xx.xx.xx 四个字节表示

1.3.4.每一个十进制数的范围 0-255

1.3.5.ip地址的组成=网络地址主机地址 192.168.43.xx

1.3.6.IPv6互联网工程任务组设计的用于替代IPv4的下一代IP协议  IPv6用16个字节表示

1.3.7.IPv4最大的问题是网络地址资源有限 严重制约了互联网的应用和发展 IPv6的使用 不仅能解决网络地址资源数量的问题 而且也解决了多种接入设备(手环 智能音箱 不止主机)连入互联网的阻碍  IPv6的地址号可以为地球上的每一粒沙子编号使用了16个字节 

1.4域名

ip地址映射成域名 

域名的出现旨在解决IP地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点

十几位的IP地址很难记 但是有了域名就好记多了 特别是域名还可以显示组织名称如百度 

www.baidu.com 百度

1.5端口

IP+端口    IP(域名)相当于一个房间(百度主页) 端口号相当于房间里不同的门(不同的程序 如淘宝 qq都有自己的端口)

博主本人并没有学过计算机网络 这一块可能写的不够好 请诸位多多见谅

1.5.1.概念:用于标识计算机上某个特定的网络程序

1.5.2.表示形式:以整数形式 范围0-65535

1.5.3.0-1024已经被占用 比如ssh22

1.5.4.常见的网络端口号 tomcat:8080 mysql :3306

1.6网络通信协议

协议是一套众所周知的规则和标准,如果各方都同意使用,那么它们之间的通信将变得毫无障碍。

协议:在网络编程数据的组织形式 表示协议    回复数据(消息)也需要按照规定好的协议方式

TCP:传输控制协议              IP:因特网互联协议

关于TCP IP 和UDP的具体信息大家可以参考一下这位博主的

TCP/IP协议,TCP和UDP的区别及特点_zzfightingy的博客-CSDN博客

TCP协议; 传输控制协议

1.使用TCP协议前 必须先建立TCP连接 形成传输数据通道

2.传输前 采用三次握手方式 是可靠的

3.TCP协议进行通信的两个应用进程客户端和服务端

4.在连接中可以进行大数据量的传输

5.传输完毕 需释放已建立的连接 效率低

UDP协议 用户数据协议

1.将数据源 目的封装数据包 不需要建立连接

2.每个数据包的大小限制在64k不适合传输大量数据

3.因无需连接 故是不可靠

4.发送数据结束时无需释放资源 速度快

二 Socket

1.基本介绍

1.1套接字(Socket)开发网络应用程序被广泛采用 以至于成为事实上的标准

1.2通信的两端都要有Socket 是两台机器间通信的端点

1.3网络通信其实就是Socket间的通信

1.4Socket允许程序把网络连接当成一个流 数据在两个Socket之间通过IO流传输

1.5一般主动发起通信的应用程序属客户端 等待通信请求的为服务端

1.6 Socket有两个方法getOutputStream和getInputStream

1.7 两种方式 一种是TCP网络通信编程(可靠) 另外一种是UDP编程(不可靠)

1.8 客户端和服务端通常情况下是在不同主机的

2.TCP网络通信编程

2.1基本介绍

1.基于客户端服务端的网络通信

2.底层使用的是TCP/IP协议

3.应用场景举例:客户端发送数据 服务端接受并显示在控制台

4.基于Socket的TCP编程

2.2 应用案例一(字节流)

1.编写一个服务器端 和一个客户端

2.服务器端在9999端口监听

3.客户端连接到服务器端

4.服务器端接收到客户端发送的信息 输出 并退出

注意写的是两个程序 服务器端和客户端

服务端

public class ServerShow {
    public static void main(String[] args) throws IOException {
        //服务端
        //1.服务器端在9999端口接听
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("客户端正在9999端口监听");
        //2.如果客户端成功连接上就返回一个Socket对象
        Socket accept = serverSocket.accept();//
        System.out.println("客户端已经连接到服务端");
        //3.接收读入
        InputStream inputStream = accept.getInputStream();
        byte[] buf = new byte[1024];
        int readlen = 0;
        while ((readlen=inputStream.read(buf))!=-1){
            System.out.println(new String(buf,0,readlen));
        }
        //4.关流
        inputStream.close();
        accept.close();
        System.out.println("服务端退出");
    }
}

客户端

public class ClientShow {
    public static void main(String[] args) throws IOException {
        //客户端
        //1.表示连接的是本机的9999端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //2.发送内容
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello server".getBytes());
        //3.关流
        outputStream.close();
        socket.close();
        System.out.println("客户端已经退出了");
    }
}

2.3应用案例二

在已写代码基础上增加互相通信的功能

服务端

public class ServerShow {
    public static void main(String[] args) throws IOException {
        //服务端
        //1.服务器端在9999端口接听
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("客户端正在9999端口监听");
        //2.如果客户端成功连接上就返回一个Socket对象
        Socket accept = serverSocket.accept();//
        System.out.println("客户端已经连接到服务端");
        //3.接收读入
        InputStream inputStream = accept.getInputStream();
        byte[] buf = new byte[1024];
        int readlen = 0;
        while ((readlen=inputStream.read(buf))!=-1){
            System.out.println(new String(buf,0,readlen));
        }
        OutputStream outputStream = accept.getOutputStream();
        outputStream.write("hello 吃火锅".getBytes());
        //结束标记
        accept.shutdownOutput();
        //4.关流
        inputStream.close();
        accept.close();
        serverSocket.close();
        outputStream.close();
        System.out.println("服务端退出");
    }
}

客户端

public class ClientShow {
    public static void main(String[] args) throws IOException {
        //客户端
        //1.表示连接的是本机的9999端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //2.发送内容
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello server".getBytes());
        socket.shutdownOutput();
        //3.接收内容
        InputStream inputStream = socket.getInputStream();
        byte[] buf=new  byte[1024];
        int readline=0;
        while((readline=inputStream.read(buf))!=-1){
            System.out.println(new String(buf,0,readline));
        }
        //结束标记
        socket.shutdownInput();
        //4.关流
        outputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("客户端已经退出了");
    }
}

2.4应用案例三(字符流)

1.编写一个服务端和一个客户端

2.服务端在9999端口监听

3.客户端连接到服务端 发送"hello server",并接受服务端回发的"hello,client"再退出

4.服务端接受到客户端发送的信息 输出 并发送"hello client"再退出

服务端


public class ServerShow01 {
    public static void main(String[] args) throws IOException {
        //服务端
        //1.等待9999端口被连
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端等待被连接");
        Socket accept = serverSocket.accept();
        //2.接收输入
        InputStream inputStream = accept.getInputStream();
        //3.字节流转化为字符流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s =bufferedReader.readLine();
        System.out.println(s);
        //4.z准备输出
        OutputStream outputStream = accept.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello client");
        bufferedWriter.newLine();
        bufferedWriter.flush();
       bufferedWriter.close();
        bufferedReader.close();
        accept.close();
        System.out.println("服务端退出");
    }
}

客户端

public class ClientShow01 {
    public static void main(String[] args) throws IOException {
        //客户端
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        //输出
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello server");
        bufferedWriter.newLine();//插入一个换行符 表示显示的内容结束 要求对方使用readLine()
        //如果使用字符流 需要手动刷新 否则数据不会写入数据通道
        bufferedWriter.flush();
        //输入
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);
        bufferedReader.close();
        outputStream.close();
        inputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

2.5互相传送一个文件(音频 图片等)

服务端代码

public class TCPFileUpLoadServer {
    //服务端
    public static void main(String[] args) throws Exception {
        //1.服务端在本机监听8888端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务端在8888端口监听....");
        //2.等待客户端连接
        Socket socket = serverSocket.accept();
        //3.读取客户端发送的数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);//文件字节数组已经写入服务端的内存中
        //4.将得到的bytes数组 写入指定的路径 得到一个文件
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:\\2.png"));
        bufferedOutputStream.write(bytes);

        bis.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出.......");
    }
}

客户端代码

public class TCPFileUpLoadClient {
    public static void main(String[] args) throws Exception {
        //客户端连接服务端
        Socket socket = new Socket(InetAddress.getLocalHost(),8888);
        //创建读取磁盘文件的输入流
        String filepath = "d:\\girl.png";
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filepath));
        //直接转换为bytes文件数组
        byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
        //输出流
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
        bufferedOutputStream.write(bytes);//将文件对应的字节数组的内容 写入到数据通道中
        socket.shutdownOutput();

        bufferedInputStream.close();
        bufferedOutputStream.close();
        socket.close();

        System.out.println("客户端关闭了......");
    }
}

StreamUtils  

public class StreamUtils {
    public static byte[] streamToByteArray(InputStream is) throws Exception{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[]b=new byte[1024];
        int len;
        while((len=is.read(b))!=-1){
        bos.write(b,0,len);
        }
        byte[] array = bos.toByteArray();
        bos.close();
        return array;
    }
    public static String steamToString(InputStream is)throws Exception{
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while((line=bufferedReader.readLine())!=null){
        stringBuilder.append(line+"\n");
        }
        return  stringBuilder.toString();
    }
}

2.6 netstat指令

1.netstat -an可以查看当前主机网络情况 包括端口监听情况和网络连接情况

2.netstat -an|more可以分页显示

3.要求在dos控制台下执行

1.LISTENING表示某个端口在监听

2.如果有一个外部程序(客户端)连接到该端口 就会显示一条连接信息

3.可以使用ctrl+c退出程序

4.以管理员身份运行dos 输入netstat -anb即可查看具体是什么程序在监听

UDP网络编程

基本介绍

1.类DatagramSocket和DatagramPacket实现了基于UDP协议网络程序

2.UDP数据报通过数据套接字DatagramSocket发送和接收 系统不保证UDP数据报一定能够安全送到目的地 也不能确定什么时候可以抵达(不可靠)

3.DatagramPacket对象封装了UDP数据报 在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号

4.UDP协议中每个数据报都给出了完整的地址信息 因此无需建立发送方和接收方的连接

基本流程

1.核心的两个类DatagramSocket和DatagramPacket

2.建立发送端 接收端

3.建立数据报

4.调用DatagramSocket的发送 接收方法

5.关闭DatagramSocket

说明

1.UDP没有明确的客户端和服务端 演变成数据的发送端和接收端

2.接收数据和发送数据是通过DatagramSocket对象完成的

3.将数据封装到DatagramPacket对象(装包) 发送

4.当接收到DatagramPacket对象后 需要进行拆包 取出数据

5.DatagramSocket可以指定在那个端口接收数据

应用案例

1.编写一个接收端A和一个发送端B

2.接收端A在9999端口等待接收数据

3.发送端B向接收端A发送数据"hello 明天吃火锅"

4.接收端A接收到发送端B的数据 回复“好的明天见” 再退出

5.发送端接收回复的数据 再退出

发送端

public class UDPSenderD {
    public static void main(String[] args) throws IOException {
        //1.创建DatagramSocket对象 准备发送和接受数据
        //发送端也可以接受数据 所以它也可以指定端口
        DatagramSocket datagramSocket = new DatagramSocket(9998);
        //2.将需要发送的数据装包DatagramPacket对象中
        byte[] bytes = "明天约会吧".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(),9999);
        //3.发送数据报
        datagramSocket.send(packet);
        //4.接受数据
        byte[] buf= new byte[1024];
        packet=new DatagramPacket(buf, buf.length);
        datagramSocket.receive(packet);
        int length = packet.getLength();
        byte[] data = packet.getData();
        String s =new String(data,0,length);
        System.out.println(s);
        //5.关闭资源
        datagramSocket.close();


    }
}

接收端

public class UDPReceiveB {
    public static void main(String[] args) throws IOException {
        //1.在9999端口监听等候
        DatagramSocket datagramSocket = new DatagramSocket(9999);
        //2.构建一个DatagramPacket对象 准备接受数据
        byte[]buf= new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf,buf.length);
         //3.调用接收方法 将通过网络传输的DatagramPacket对象 填充到packet对象
        datagramSocket.receive(packet);
        //4.可以把packet进行拆包 取出数据
        int length = packet.getLength();
        byte[]data= packet.getData();
        String s = new String(data,0,length);
        System.out.println(s);
        //5.回复消息
        byte[] bytes="好的".getBytes();
        DatagramPacket packet1 = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),9998);
        datagramSocket.send(packet1);
        //6.关闭资源
        datagramSocket.close();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值