javaSE--进阶十五(网络编程,TCP与UDP)

网络编程的三要素

ip地址:ip地址网络中计算设备的唯一标识
	ipv4:4个字节
	ipv6:16个字节
	
	ipconfig: 查看本机的ip地址
	ping: 检测指定的ip是否能够连接通
	
	注意:ip地址和域名是对应的,需要在工信部门进行备案
	
端口号:计算设备中连接网络的应用程序的标识(用一个整数表示 0~655350~1023不建议使用,可能会被系统或者一些知名的软件占用。
	80:连接互联网的默认端口号
	
协议:网络中数据传输的规则
	UDP协议:面向无连接,不可靠的通信协议
	TCP协议:面向有链接,可靠的通信协议

InetAddress类

InetAddress表示IP地址对象

//获取ip地址对象
InetAddress address = InetAddress.getByName("192.168.72.202");
//获取主机名
System.out.println(address.getHostName());

UDP通信

发送端

//1.创建DatagramSocket对象(邮局)
DatagramSocket ds=new DatagramSocket();

//2.创建DatagramPacket对象(打包裹)
//字节数组:数组中就是需要传输的数据
//数组的长度:数据有多大
//ip地址:数据包需要发送到哪台主机
//端口号:找到对方哪个应用程序接受

byte[] bs="你好世界".getBytes();
int length=bs.length;
InetAddress ip= InetAddress.getByName("127.0.0.1"); //主机本机的ip地址
int port=10000;
DatagramPacket dp=new DatagramPacket(bs,length,ip,port);

//3.发送数据包(把包裹交给邮局)
ds.send(dp);

//4.释放资源
ds.close(); 

接收端

//1.创建DatagramSocket对象(邮局)
DatagramSocket ds=new DatagramSocket(10000);

//2.创建DatagramPacket对象(用来接受数据的包裹)
byte[] bs=new byte[1024];
DatagramPacket dp=new DatagramPacket(bs,bs.length);

//3.接受数据(自动把接受的到数据,填充到包裹中)
ds.receive(dp); //阻塞(等待发送端发送数据)

//4.解析数据(拆包裹)
byte[] data = dp.getData();
int length = dp.getLength();

//通过数组和长度转换为一个字符串
String str=new String(data,0,length);

//获取ip地址
InetAddress address = dp.getAddress();
System.out.println(address+str);

//5.释放资源
ds.close();

单播、组播、广播

单播:一个发送端 发给 一个接收端
	使用DatagramSocket进行发送和接收 

组播:一个发送端 发给 多个接收端(一组)
	
	//创建MulticastSocket对象
    MulticastSocket MS=new MulticastSocket(10000);
	//把当前地址加入组: 组播地址:224.0.1.0
    MS.joinGroup(InetAddress.getByName("224.0.1.0"));

广播:一个发送端 发给 所有接收端
	//广播地址:255.255.255.255
	使用DatagramSocket进行发送和接收

TCP通信

TCP通信的流程图

  • 客户端代码
public class Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象(客户端),指定服务端的ip和端口号
        Socket socket=new Socket("127.0.0.1",10086);

        //获取通往服务端的OutputStream
        OutputStream out = socket.getOutputStream();
        //往服务端写数据
        out.write("HelloWorld".getBytes());

        /**********************/

        //获取输入流,用来读取服务端发过来的数据
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len=in.read(bs);

        String str=new String(bs,0,len);
        System.out.println(str);

        //释放资源
        socket.close();
    }
}
  • 服务端代码
public class Server {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象
        ServerSocket serverSocket=new ServerSocket(10086);
        //监听客户端(迎宾)
        Socket socket = serverSocket.accept(); //阻塞(等着客户端连接)

        //获取输入流对象
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len = in.read(bs);
        System.out.println(new String(bs,0,len));


        /*******************/
        //获取通往客户端的输出流
        OutputStream out = socket.getOutputStream();
        out.write("你好世界".getBytes());

        //释放资源
        socket.close();
        serverSocket.close(); 
    }
}

在这里插入图片描述

文件上传的原理

在这里插入图片描述

客户端

public class UploadClient{
    public static void main(String[] args) throws IOException {
        //创建Socket对象
        Socket socket=new Socket("127.0.0.1",10010);
        //获取输出流(通往服务器)
        OutputStream out=socket.getOutputStream();

        //读取本地的图片 a.jpg
        FileInputStream fis=new FileInputStream("myModule15\\a.jpg");
        byte[] bs=new byte[1024];
        int len; //记录每次读取的字节个数
        while((len=fis.read(bs))!=-1){
            //往服务写数据
            out.write(bs,0,len);
        }
        //告诉服务端,数据写完了(告诉服务端可以读取到一个结束标记)
        socket.shutdownOutput(); 

        //读取服务端返回的数据
        InputStream in = socket.getInputStream();
        len= in.read(bs);
        System.out.println(new String(bs,0,len));

        //释放资源
        fis.close();
        socket.close();
    }
}

服务端

public class UploadServer {
    public static void main(String[] args) throws IOException {
        //创建服务端的Socket对象
        ServerSocket serverSocket=new ServerSocket(10010);
        //获取客户端的Socket对象
        Socket socket = serverSocket.accept();

        //创建FileOutputStream,用来往服务端本地写数据
        FileOutputStream fos=new FileOutputStream(new File("C:\\Users\\it\\Desktop\\upload",UUID.randomUUID().toString()+".jpg"));

        //获取输入流,读取客户端发过来的数据
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len; //每次读取的有效个数
        while ((len=in.read(bs))!=-1){
            fos.write(bs,0,len);
        }
        fos.close();


        //告诉客户端,上传成功
        OutputStream out = socket.getOutputStream();
        out.write("上传成功".getBytes());

        //释放资源
        socket.close();
        serverSocket.close();
    }
}

多线程改进服务端

在这里插入图片描述

  • 服务端处理文件上传的任务
//上传文件的任务
public class UploadRunnable implements Runnable {
	//上传文件的操作需要一个Socket,但是不知道这个Socket是水
    private Socket socket;
    public UploadRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() { 
        FileOutputStream fos=null;
        try {
            //创建FileOutputStream,用来往服务端本地写数据
            File file=new File("C:\\Users\\it\\Desktop\\upload", UUID.randomUUID().toString()+".jpg");
            fos=new FileOutputStream(file);

            //获取输入流,读取客户端发过来的数据
            InputStream in = socket.getInputStream();
            byte[] bs=new byte[1024];
            int len; //每次读取的有效个数
            while ((len=in.read(bs))!=-1){
                fos.write(bs,0,len);
            }

            //告诉客户端,上传成功
            OutputStream out = socket.getOutputStream();
            out.write("上传成功".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally { //不管异常发不发生,finally的代码都会执行
            //释放本地的流
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //释放资源
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 服务端代码,来一个Socket就为其开一条线程
public class UploadServer {
    public static void main(String[] args) throws IOException {
        //创建服务端的Socket对象
        ServerSocket serverSocket=new ServerSocket(10010);

        while (true){
            //获取Socket对象
            Socket socket = serverSocket.accept();
            //创建线程任务
            UploadRunnable r=new UploadRunnable(socket);
            //创建线程
            new Thread(r).start();
        }

        //serverSocket.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值