首页 > 编程语言 >Java网络编程--Lesson

Java网络编程--Lesson

时间:2023-11-29 23:13:54浏览次数:37  
标签:Java socket -- packet buffer close new Lesson byte

一.InetAddress

此类是获取网络地址实例的一个类,但是不能通过new 来实例化这个类,因为它没有构造器,但是可以通过组合的方式来使用类中的方法

拿取主机为localhost的网络地址实例

InetAddress address=InetAddress.getByName("localhost");

 

拿取百度网络地址实例

//拿取主机为www.baidu.com的网络地址实例
InetAddress BaiDu=InetAddress.getByName("www.baidu.com");

 

通过地址实例拿取详细的地址信息

  • 拿取IP地址
//获得真实的IP地址
System.out.println(BaiDu.getCanonicalHostName());
  • 拿取主机名称
//获得地址的主机名 or 域名
System.out.println(BaiDu.getHostName());

 

二.InetSocketAddress

InetSocketAddress也是.net包下的一个类,它的作用是拿取主机的特定端口信息 如拿取百度的80端口信息:
//拿取百度的80端口信息
InetSocketAddress socketAddress = new InetSocketAddress("www.baidu.com", 80);
System.out.println(socketAddress);

 通过new关键字可以实例化InetSocketAddress类,从而通过此对象的方法继续拿到其它信息

  • 地址信息
//获取地址信息
System.out.println(socketAddress.getAddress());
  • 主机信息
//获取主机名称
System.out.println(socketAddress.getHostName());

 

  • 端口信息
//获取端口号
System.out.println(socketAddress.getPort());

 三.模拟使用

TCP实现文件上传

模拟两个角色,一个用户端,一个服务器端

用户端负责发送,服务器端负责接收,

  • 模拟用户端:

TCP连接需要的参数对方的IP地址和端口

//1.创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),5206);

 

建立连接以后需要读取文件再发送给服务器端

//2.创建一个文件输出流
OutputStream outs = socket.getOutputStream();
//3.读取文件
FileInputStream file = new FileInputStream(new File("kq.png"));

 

开始向服务器端写出数据

 

//4.写出文件
byte[] buffer = new byte[1024];
int len;
while ((len=file.read(buffer))!=
    outs.write(buffer,0,len);
}
//通知服务器已经完成了传输
socket.shutdownOutput();

 

等待服务器发送结束标志

//接收服务器端发送的结束标志
InputStream stream = socket.getInputS
ByteArrayOutputStream baos = new Byte
byte[] bytes = new byte[1024];
int len1;
while ((len1=stream.read(buffer))!=-1
    baos.write(buffer,0,len1);
}
System.out.println(baos.toString());

 

收到服务器发送的接收完成的标志,关闭客户端资源

//关闭资源
file.close();
baos.close();
outs.close();
socket.close();

 

  • 模拟服务器端

创建一个连接,并开启需要使用到的端口

//1.创建服务
ServerSocket serverSocket = new ServerSocket(5206);

 

阻塞式监听端口,直到有客户端发来连接

//2.监听用户端口
Socket accept = serverSocket.accept();

 

获取客户端发送的IO流文件

//3.获取输入流
InputStream io = accept.getInputStream();
//4.文件输出流
FileOutputStream file = new FileOutputStream(new File("刻晴.png"));

 

写出IO流文件内容

byte[] buffer = new byte[1024];
int len;
while ((len=io.read(buffer))!=-1){
    file.write(buffer,0,len);
}

 

写出完成后,向客户端发送读取完成标志,并关闭资源

//向客户端发送数据读取完成标志
OutputStream os = accept.getOutputStream();
os.write("我已经读取完成了".getBytes());
//关闭资源
file.close();
io.close();
accept.close();
serverSocket.close();

 

UDP实现信息发送

Udp和TCP传输的最大区别在于Udp是无连接的,它传送不像Tcp需要事先预告,而是直接发向目的地址

TCP的传输就好比打电话,在你呼叫的时候可以选择不接,也可以选择接,这就是连接,如果 想和对方通话,那么对方就必须接并且建立联系

UDP的传输就好比发送消息,你不能选择不接收,就算关机,也只是延迟收到,而发送方只管一键发送,并不在乎你是否收到

所以在下面的实现中,是没有连接的过程的,但是还是需要对方的地址和端口,这是目的地必须要知道,只是不需要链接了

  • 模拟客户端

建立一个socket对象用来发送报文

//1.建立一个socket,发送报文
DatagramSocket socket = new DatagramSocket();

 

发送方的信息及内容

//2.发送方信息即数据
String msg="i miss you";
InetAddress address =InetAddress.getByName("localhost");
int port=5206;

 

打包一个数据包

//3.数据包,数据,数据的长度起始,要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, address, port);

 

发送包,完成,关流

//4.发送包
socket.send(packet);
//5.关闭流
socket.close();

 

 

  • 模拟服务器端

开放端口

//开放端口
DatagramSocket socket = new DatagramSocket(5206);

 

接收并展示数据包

//2.接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);//阻塞式接收
System.out.println(packet.getAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));

 

关闭连接

//3.关闭连接
socket.close();

模拟服务器端接收到的参数

 模拟连续对话

使用Udp发消息的基础上,在加上一个循环语句就是可以实现连续对话的

我们模拟的场景是,连续对话也就是一端既要接收数据,又要发送数据

那么我们就可以使用多线程编程,一个线程负责发送消息,一个线程负责接收消息

  • 搭建发送的线程类

多线程需要实现Runnable接口,并且重写Run方法

run方法

    @Override
    public void run() {
        int count=10;
        while (count>0){
            String data = null;
            //接收数据,控制台读入
            sysIn = new BufferedReader(new InputStreamReader(System.in));
            try {
                data = sysIn.readLine();
                byte[] dataBytes = data.getBytes();
                DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, InetAddress.getByName(ToIP), ToPort);
                socket.send(packet);
                count--;
                if (data.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //关闭流
        socket.close();
    }

 

创立一个socket对象的代码被提升作用域到构造器中了

构造方法

public class UdpTalkSend implements  Runnable{
    DatagramSocket socket = null;
    BufferedReader sysIn = null;
    private int MyPort;
    private String ToIP;
    private int ToPort;

    public UdpTalkSend(int myPort, String toIP, int toPort) {
        this.MyPort = myPort;
        this.ToIP = toIP;
        this.ToPort = toPort;
        try {
            socket = new DatagramSocket(MyPort);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void run() {
    }
}

 

  • 搭建接收的线程

重写run方法

    @Override
    public void run() {
        int count=10;
        while (count>0){
            try {
                //准备接收数据包
                byte[] bytes = new byte[1024];
                packet = new DatagramPacket(bytes, 0, bytes.length);
                socket.receive(packet);
                String data = new String(packet.getData(), 0, packet.getLength());
                System.out.println(username+":"+data);
                count--;
                if (data.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
        //关闭流
        socket.close();
    }

 

构造方法

public class UdpTalkReceive implements Runnable {
    DatagramSocket socket = null;
    DatagramPacket packet = null;
    private int ToPort;
    private String username;

    public UdpTalkReceive(int toPort, String username) {
        ToPort = toPort;
        this.username = username;
        try {
            socket = new DatagramSocket(ToPort);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public void run() {
    }
}

 

模拟两个用户A和B

A:

public class UserClientA {
    public static void main(String[] args) {
        new Thread(new UdpTalkReceive(5202,"B")).start();
        new Thread(new UdpTalkSend(5203,"127.0.0.1",5201)).start();
    }
}

 

B:

public class UserClientB {
    public static void main(String[] args) {
        new Thread(new UdpTalkReceive(5201,"A")).start();
        new Thread(new UdpTalkSend(5204,"localhost",5202)).start();
    }
}

 

测试结果:

 四.使用java.net.URL类下载

我使用的是在网易云上下载了一首音乐下来

获取下载路径:

//得到url路径资源
URL url = new URL("https://m801.music.126.net/20231129230405/aabdfb2ffd40439ec5c68a80c11a0140/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/14096410414/5dd8/3527/d0a8/2bc39cc62c984590b57fff0024c23780.m4a");

 

和URL地址创建连接

//创建连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

 

下载也是IO流,所以创建一个流

//创建写入流
InputStream io = connection.getInputStream();
FileOutputStream file = new FileOutputStream(new File("世界美好.m4a"));

 

利用IO流将.m4a文件写入到本地

//开始写入
byte[] buffer = new byte[1024];
int len;
while ((len=io.read(buffer))!=-1){
    file.write(buffer,0,len); //写出数据
}

 

断开连接

//断开连接
file.close();
io.close();
connection.disconnect();

 

最后在本地会得到一个.m4a文件

 

标签:Java,socket,--,packet,buffer,close,new,Lesson,byte
From: https://www.cnblogs.com/5ran2yl/p/17860743.html

相关文章

  • day02
    快捷键ctrl+c复制ctrl+v粘贴alt+f4关闭窗口ctrl+shift更换输入法alt+tabwindows+tab打开小窗口ctrl+a全选ctrl+x剪切ctrl+z撤销ctrl+s保存shift+delete永久删除windous+e我的电脑ctrl+shift+esc任务管理器 功能键tab键切换菜单shift组合键ctrl......
  • 聪明方法学python task5 条件/代码风格
    条件控制elif代替了C语言中的elseif缩进划分代码块嵌套if仍然成立多返回语句defabs(n):  ifn<0:    return-n  returnn match-case类比switch-case语句_可以匹配一切。deftest(a):​•matcha:​•case1:​•......
  • 聪明办法学python第三次打卡
    #ifelse语句if: else: #elif语句:if: elif: else: #match-case语句:matchmcase1: case2: case3: case4: case5: 一个case也可以设置多个匹配条件,条件使用|隔开......
  • CF1846E2 Rudolf and Snowflakes (hard version) 题解
    题意:\(T\)\((\)\(1\)\(\le\)\(T\)\(\le\)\(10^4\)\()\)组询问:是否存在一个满\(k\)(\(k\)\(\ge\)\(2\)\()\)叉树节点数恰好为\(n\)\((\)\(1\)\(\le\)\(n\)\(\le\)\(10^{18}\)\()\),且深度\(depth\)至少为\(2\)。思路:满$k$......
  • 优雅代码
    优雅代码part1写注释方便自己看,也方便别人阅读tab键相当于4空格换行与缩进换行符\导入规范假设目录:Tree|___m1.py|___m2.py|___Branch |___m3.py |___m4,py在m2.py写代码defprintself(): print("m2")在m3.py写代码defprintself(): print("m3")import本地......
  • 条件
    条件if语句绝对值defabs2(n): ifn<0: n=-n returnnif-else语句x=input("x")x=float(x)print("hello")ifx<10: print("wa")else: print("ro")print("goodbye")x=10hellorogoodbye重新设计absdefabs......
  • 记录下当前的心情
    其实到今年23年,毕业马上快4年了,之间换过2份工作,第一份外包,第二份一家小的自研公司,回头看的话,发现自己一直在得过且过,躺的直直的,在工作中遇到问题了回去想办法解决,但是也仅限于此了,驱动力全是工作遇到的问题,问题解决后就万事大吉,从来没主导拿过去了解过底层的实现原理或者逻辑......
  • tmp
    证明:积性函数的和函数仍是积性函数。建议先看底下的欧拉函数的积性证明,这个证明的很乱。看能不能把一一对应写得更数学抽象严谨一点。推了两个午自习但是不是很难的式子,用了\(80\)分钟是因为人是憨憨。证明不是很严谨。设算术函数\(F(x)=\sum_{d|x}f(d)\),其中\(f\)是......
  • Lemonsqueezy教程:Stripe的最好替代品
    Lemonsqueezy优点• 申请门槛低:国内用户也可以申请,不需要公司资质• 支付微信支付和支付宝:详情见这里[1]• 支持试用• 有佣金系统• 有折扣码系统对比支付网关服务名称费率支持的支付方式安全性客户服务和支持PayPay2.9%+0.30美元信用卡、借记卡、银行转账、PayPal余额等金......
  • 【Python爬虫】第13篇:scrapy项目配置和数据获取。从0到scrapy高手笔记(附代码,可自取)
    本文主要学习一下关于爬虫的相关前置知识和一些理论性的知识,通过本文我们能够知道什么是爬虫,都有那些分类,爬虫能干什么等,同时还会站在爬虫的角度复习一下http协议。全套笔记和代码自取地址:请移步这里感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~共8章,37子模块scrapy爬......