Java大数据之路--套接字(TCP、UDP)

  • 网络编程(套接字)

目录

网络编程(套接字)

网络模型

SocketAddress(代表IP地址的类)

 UDP

TCP


通过java程序实现网络之间的数据传输,底层基于网络来传输的流。

  • 网络模型

IP地址:确定在网络中的位置,IPv4 由4位0-255之间的数组成

端口:计算机和外部进行数据交互的媒介-----端口号(0-65535) 0-1024这些端口号大部分已经被系统占用,自己使用端口号的时候就从1025往后找

www.baidu.com----域名   通过DNS可以映射到对应的IP

  • SocketAddress(代表IP地址的类)

Constructor and Description
InetSocketAddress(InetAddress addr, int port)

从IP地址和端口号创建一个套接字地址。

InetSocketAddress(int port)

一个套接字地址,IP地址掩码地址和端口号指定的价值创造。

InetSocketAddress(String hostname, int port)

根据主机名和端口号创建一个套接字地址。

Modifier and TypeMethod and Description
static InetSocketAddresscreateUnresolved(String host, int port)

根据主机名和端口号创建一个悬而未决的套接字地址。

booleanequals(Object obj)

将此对象与指定的对象进行比较。

InetAddressgetAddress()

得到 InetAddress

StringgetHostName()

得到 hostname

StringgetHostString()

返回主机名或地址的字符串形式,如果它没有一个主机名(这是用文字创造的)。

intgetPort()

获取端口号。

inthashCode()

返回该套接字地址的hash码。

booleanisUnresolved()

检查地址是否已被解决或不。

StringtoString()

构造此InetSocketAddress的字符串表示形式。

public class InetSocketAddressDemo {
    public static void main(String[] args) {
        //创建表示IP和端口的对象
        //127.0.0.1这个IP值一直指向本地,localhost和127.0.0.1互相映射
        InetSocketAddress isa= new InetSocketAddress("localhost",8090);
        //获取IP地址
        System.out.println(isa.getAddress());
        //获取主机名
        System.out.println(isa.getHostName());
        //获取端口号
        System.out.println(isa.getPort());
    }
}
  •  UDP

底层基于流,不会建立链接,不可靠,传输速度快,适用场景:视频聊天等。

底层通过数据包来进行数据的传输,数据包大小一般不能超过64KB 

Class DatagramSocket、Class DatagramPacket

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;
/*
* #发送端
* */
public class UDPSender {
    public static void main(String[] args) throws IOException {
        //发送端,创建出网络编程对象-----指定要发送端的端口
        DatagramSocket ds = new DatagramSocket(8009);
        Scanner sc  = new Scanner(System.in);
        String s= sc.nextLine();
        //创建数据包
        //第一个参数要传输的字节数组
        //第二个参数真正要发送的数据长度
        //第三个参数知名要传输的IP地址和端口号
        DatagramPacket dp = new DatagramPacket(s.getBytes(),s.getBytes().length,new InetSocketAddress("127.0.0.1",8080));
        //发送数据包
        ds.send(dp);
        //关流----关闭底层字节流
        ds.close();
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/*
* #接收端
* */
public class UDPReceiverDemo {
    public static void main(String[] args) throws IOException {
        //创建套接字对象
        DatagramSocket ds= new DatagramSocket(8080);
        //创建数据包用于接收数据----第二个参数代表实际接收数据长度
        DatagramPacket dp = new DatagramPacket(new byte[1024],1024);
        //接收数据,把接收到的数据放到数据包中
        ds.receive(dp);
        //关流
        ds.close();
        //解析数据包
        //dp.getData---获取数据---字节数组
        //dp.getLength()----获取数据长度
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        //获取ip地址
        System.out.println(dp.getAddress());
        //获取端口号
        System.out.println(dp.getPort());
    }
}

发送端:

1、创建套接字对象

2、创建需要发送端数据包(指定要发送的数据长度以及IP地址和端口号)

3、发送数据包

4、关流

接收端:

1、创建套接字对象(绑定具体的端口号)

2、创建需要接收的数据包(指定真实接收数据长度)

3、接收数据包

4、关流

5、解析数据包

案例:通过UDP协议实现简易的聊天室(通过线程来实现)

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Scanner;

public class ChatDemo1 {
    public static void main(String[] args) {
    //开启线程
        new Thread(new Sender()).start();
        new Thread(new Receiver()).start();
    }
}
class Sender implements Runnable{
    //申明对象
    DatagramSocket ds;
    Scanner sc;
    @Override
    public void run() {
        //对象初始化
        try {
            ds=new DatagramSocket();
            sc=new Scanner(System.in);
            while (true){
                //录入数据
                byte[] bs =sc.nextLine().getBytes();
                //创建发送的数据包
                DatagramPacket dp = new DatagramPacket(bs,bs.length,new InetSocketAddress("127.0.0.1",8090));
                //发送
                ds.send(dp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class Receiver implements  Runnable{
    DatagramSocket ds;
    DatagramPacket dp;
    @Override
    public void run() {
        //对象初始化
        try {
            ds=new DatagramSocket(8090);
            dp=new DatagramPacket(new byte[1024],1024);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        while (true){
            //接收数据包
            try {
                ds.receive(dp);
                //解析数据包
                System.out.println(new String(dp.getData(),0,dp.getLength()));
                System.out.println(dp.getAddress());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • TCP

底层基于流,建立链接(三次握手),可靠,传输速度慢,TCP通过字节流直接传输数据不需要数据包,就没有传呼数据的限制,适用场景:传输文件、下载电影等。

Socket、ServerSocket

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/*
* #客户端
* */
public class TCPClientDemo {
    public static void main(String[] args) throws IOException {
        //创建套接字对象
        Socket s = new Socket();
        //发起链接---指定链接的IP和端口
        //connect会发生阻塞
        s.connect(new InetSocketAddress("127.0.0.1",8010));
        //获取自带的字节输出流,写出的数据默认往服务器端写
        OutputStream os =s.getOutputStream();
        //通过自带数据输出流来写数据
        //也有阻塞
        os.write("服务器你好。。。".getBytes());
        //通知服务器端数据已写完
        s.shutdownOutput();
        //获取自带的字节输入流
        InputStream is =s.getInputStream();
        byte[] bs = new byte[1024];
        int len = -1;
        while ((len=is.read(bs))!=-1){
            System.out.println(new String(bs,0,len));
        }
        s.shutdownInput();
        //关流
        os.close();
    }
}
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* #服务器端
* */
public class TCPServerDemo {
    public static void main(String[] args) throws IOException {
        //创建TCP服务器端对象----绑定端口
        ServerSocket ss= new ServerSocket(8010);
        //接收链接-----返回一个Socket对象
        //阻塞
        Socket s=ss.accept();
        //读取传过来的数据
        InputStream is =s.getInputStream();
        //通过自带的输入流来获取
        //自建缓冲区
        byte[] bs = new byte[1024];
        int len = -1;
        while ((len=is.read(bs))!=-1){//读取有阻塞
            System.out.println(new String(bs,0,len));
        }
        //通知客户端数据已读完
        s.shutdownInput();
        //关流
        //获取自带的字节输出流
        OutputStream os=s.getOutputStream();
        //往客户端写出数据
        os.write("你好我也好。。。。".getBytes());
        //通知客户端已经写完
        s.shutdownOutput();
        is.close();
    }
}

客户端:

1、创建TCP客户端对象

2、发起链接(指明要发送的IP和端口)

3、获取自带的字节输出流

4、根据自带的字节流往服务器端写出数据

5、通知服务端已经写完数据

6、关流

服务器端:

1、创建TCP服务端对象,绑定端口

2、获取链接

3、获取自带的字节输入流对象

4、根据自带的字节输入流进行数据读取

5、通知客户端读取完成

6、关流

receive、connect、accept、write、read都会阻塞

通过TCP来实现文件复制

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

/*
* TCP复制文件#客户端
* */
public class FileCopyClient {
    public static void main(String[] args) throws IOException {
        //创建TCP客户端对象
        Socket s = new Socket();
        //发起链接
        s.connect(new InetSocketAddress("127.0.0.1",9009));
        //把外部文件读取进来
        FileInputStream fis = new FileInputStream("D:\\1.txt");
        //获取自带输出流
        OutputStream os =s.getOutputStream();
        //读取
        byte[] bs = new byte[1024*1024*10];
        int len=-1;
        while((len=fis.read(bs))!=-1){
            //往服务器端写数据
            os.write(bs,0,len);
        }
        //通知服务器端已写完
        s.shutdownOutput();
        //关流
        os.close();
        fis.close();
    }
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * TCP复制文件#服务器
 * */
public class FileCopyServer {
    public static void main(String[] args) throws IOException {
        //获取TCP服务器端对象绑定端口
        ServerSocket ss = new ServerSocket(9009);
        Socket s =ss.accept();
        //获取自带字节输入流--读取客户端发来的
        InputStream in =s.getInputStream();
        //创建文件字节输出流
        FileOutputStream fos = new FileOutputStream(new File("D:\\TCP1.txt"));
        byte[] bs = new byte[1024*1024*10];
        int len=-1;
        while((len=in.read(bs))!=-1){
            //往D盘写
            fos.write(bs,0,len);
        }
        //通知客户端已经读取完毕
        s.shutdownInput();
        fos.close();
    }
}

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值