网络编程

概述

计算机网络:自己百度吧

网络编程的目的:传播交流信息、数据交换、通信

想要达到这个效果需要什么:

  • 如何准确的定位网络上的一台主机 端口 定位到这个计算机上的某个资源
  • 找到了这个主机,如何传输数据呢?

javaWeb开发 :网页编程 B/S架构

网络编程:主要针对TCP/IP C/S架构

网络通信的要素

如何实现网络的通信?

通信双方地址:

  • IP
  • 端口号

规则:网络通信的协议

http ftp smtp等

IP地址

IP地址:InetAddress(没有构造器,就不用new了,new不了,用静态方法)

  • 可以唯一的定位一台网络上的计算机

  • 一些特殊的IP,如:127.0.0.1 代表本机(localhost)

  • IP地址的分类,分类方式有两种

    • 通过IP地址分类 ipv4/ipv6

      • ipv4 像127.0.1,是由4个字节组成,每个字节的长度是0-255,ipv4都给外国人了,亚洲就那几个吧,早用光了
      • ipv6 128位,8个无符号整数 0-9 a-e

      ipv6写法:

      2001:0bb2:aaaa:0000:0000:1aaa:1311:0025

    • 通过公网(互联网使用)还是私网(局域网使用)分类

    ​ 局域网:192开头的,专门给组织内部使用的

    ABCD类地址有时间自己查查

  • 域名的诞生就是为了解决记忆IP问题

package com.zhang.WLBC.Lesson01;

import java.net.InetAddress;
import java.net.UnknownHostException; //测试IP
public class TestInetAddress {
public static void main(String[] args) {
//InetAddress z=new InetAddress();没有构造器,无法new,只能通过它的静态方法把他返回过来
try {
//查询本机地址
InetAddress inetAddress1=InetAddress.getByName("127.0.0.1");//通过获取名字返回 这就代表一个IP对象 //静态方法返回的就是本身这个对象
System.out.println(inetAddress1);
InetAddress inetAddress3=InetAddress.getByName("localhost");
System.out.println(inetAddress3);//localhost/127.0.0.1
InetAddress inetAddress4=InetAddress.getLocalHost();
System.out.println(inetAddress4);//DESKTOP-VKFSHV1/192.168.1.3 //查询网站的IP地址
InetAddress inetAddress2=InetAddress.getByName("www.baidu.com");//跟ping是一样的作用
System.out.println(inetAddress2);//www.baidu.com/39.156.66.18 //常用方法
System.out.println(inetAddress2.getAddress());
System.out.println(inetAddress2.getCanonicalHostName());//获得规范的名字
System.out.println(inetAddress2.getHostAddress());//IP
System.out.println(inetAddress2.getHostName());//域名,或自己电脑的名字 } catch (UnknownHostException e) {
e.printStackTrace();
}
//上面报错了(未知的主机异常),用try catch捕获一下
} }

端口

端口表示计算机上一个程序的进程,一个端口对应一个程序的进程

  • 不同的进程有不同的端口号,用来区分软件

  • 端口被规定0-65535

  • 分为TCP端口和UDP端口,单个协议下,端口号不能冲突,但是不同协议下的端口号可以相同。如:TCP:80与UDP:80

  • 端口分类-

    公有端口:0-1023

    • HTTP:80
    • HTTP5:443
    • FTP:21
    • Telent:23

    程序注册端口:1024-49151,分配给用户或程序

    • Tomcat:8082
    • MySQL:3306
    • Oracle:1521

​ 动态或私有端口:49152-65535

常见的dos命令

netstat -ano 查看所有的端口

netstat -ano|findstr "5900" 查看指定的端口

tasklist|findstr "8696" 查看指定端口的进程

package com.zhang.WLBC.Lesson01;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress socketAddress=new InetSocketAddress("127.0.0.1",80);//这个类可以new
System.out.println(socketAddress);///127.0.0.1:80
InetSocketAddress socketAddress1=new InetSocketAddress("localhost",80);//这个类可以new
System.out.println(socketAddress1);//localhost/127.0.0.1:80 //里面的方法
System.out.println(socketAddress.getAddress());// /127.0.0.1
System.out.println(socketAddress.getHostName());//127.0.0.1
System.out.println(socketAddress.getPort());// 80
}
}

通信协议

协议:约定,就像现在说的是汉语才能听懂,说外语就jj了

网络通信协议:针对网络产生的协议

TCP/IP协议簇:实际上是一组协议

TCP:用户传输协议 类似于打电话

UDP:用户数据报协议 类似于发短信

比较出名的协议

  • TCP:用户传输协议
  • IP:网络互联协议

TCP与UDP对比

  • TCP:类似打电话

    • 连接,稳定
    • 三次握手,四次挥手

    建立稳定连接至少要三次

    断开连接至少要四次

    • 客户端,服务端连接
    • 传输完成就会释放连接,效率低
  • UDP:类似发短信

    • 不连接,不稳定
    • 客户端,服务端没有明确的界限
    • 不管有没有准备好,都可以发给你
    • DDOS:洪水(饱和)攻击,也就是人海战术吧

TCP实现聊天

​ 聊天就要两个人(客户端和服务器)

得编写两个类:客户端、服务器

客户端

  1. 通过socket连接服务器
  2. 发送消息
package com.zhang.WLBC.Lesson02;
//运行时先启动服务端,再启动客户端
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets; //客户端
public class TcpClientDemo01 {
public static void main(String[] args) {
Socket socket=null;
OutputStream os=null;
//1.客户端连接服务器要先知道服务器的地址,所以对服务器来说得先有一个地址,做一个地址
//连接
try {
InetAddress severIP=InetAddress.getByName("127.0.0.1");//要连接的地址
//2.端口号
int port =9999;
//把上面两行和服务端连接
//用socket 创建一个socket连接
socket=new Socket(severIP,port);//这样就连接到服务端了,这里会出现异常,要把catch中的作用域提升到最大(把UnknownHostException改为Exception)把UnknownHostException改为Exception
//3.发送消息,用到IO
os=socket.getOutputStream();
os.write("你好,我正在自学java".getBytes());//然后就是客户端接收了 } catch (Exception e) {//catch (UnknownHostException e) {
e.printStackTrace();
}finally {
if (os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null) {
try {
socket.close();//继续提升作用域,捕获异常
} catch (IOException e) {
e.printStackTrace();
}
} }
}
}

服务器

  1. 建立服务的端口Seversocket

  2. 通过accept等待客户端的连接,会返回客户端连接过来的socket

  3. 接收用户的消息

package com.zhang.WLBC.Lesson02;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; //服务端
public class TcpSeverDemo01 {
public static void main(String[] args) {
//提升作用域?
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.做一个地址localhost:9999,再去客户端让客户端连这个9999
serverSocket = new ServerSocket(9999);
//2.等待客户端连接过来
socket = serverSocket.accept();//这里的Socket就是客户端连接过来的socket
//3.读取客户端的消息
is = socket.getInputStream(); /* byte[] buffer=new byte[1024];//用缓冲区去接
int len;
while ((len=is.read(buffer))!=-1){//读
String msg=new String(buffer,0,len);//然后写出去,new一个string后拼接上去
System.out.println(msg);
//但一般不这样写了,因为有中文的话会乱码
}
*/
//而用管道流
baos = new ByteArrayOutputStream(); //把输入流通过管道流接一下,再输出来
byte[] buffer = new byte[1024];//用缓冲区去接
int len;
while ((len = is.read(buffer)) != -1) {//读
baos.write(buffer, 0, len);
}
System.out.println(baos.toString()); } catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源,先开后关
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!= null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();//这几行直接加不进来,要提升作用域
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} //也可以不写try catch,直接抛出异常

文件上传

读取后,把文件变成一个流,再传出去

客户端(路径一直不对,报错)

package com.zhang.WLBC.Lesson02;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket; //客户端读取发送文件
public class TcpClientDemo02 {
public static void main(String[] args) throws Exception{
//1.创建一个socket连接
Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),9000);
//2.创建一个输出流
OutputStream os=socket.getOutputStream(); //3.读取文件
FileInputStream fis= new FileInputStream(new File("B.PNG"));
//4.写出文件
byte[] buffer=new byte[1024];//缓冲区
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
} //通知服务器,我已经结束了
socket.shutdownOutput();//我已经传输完了 //确定服务器接收完毕才能断开连接,再在服务器端通知客户端我接收完毕了
InputStream inputStream=socket.getInputStream();
ByteArrayOutputStream baos=new ByteArrayOutputStream();//传过来的东西不认识,只有通过管道流才能认识 byte[] buffer2=new byte[1024];
int len2;
while ((len2=inputStream.read())!=-1){
baos.write(buffer2,0,len2);
} System.out.println(baos.toString());
//5.关闭资源
baos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
}
}

服务器端

package com.zhang.WLBC.Lesson02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; //服务端接收文件
public class TcpSeverDemo02 {
public static void main(String[] args) throws Exception{
//1.创建服务端口
ServerSocket serverSocket=new ServerSocket(9000);
//2.监听客户端的连接
Socket socket=serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//3.获取输入流
InputStream is=socket.getInputStream();//这样就把文件拿到了 //4.文件输出
FileOutputStream fos=new FileOutputStream(new File("receive.PNG"));
byte[] buffer=new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
} //通知客户端我接收完毕了
OutputStream os=socket.getOutputStream();
os.write("我接收完毕了,可以断开了".getBytes()); //关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}

Tomcat

服务端

  • 自定义s
  • 也可以用Tomcat服务器

客户端

  • 自定义c
  • 浏览器B

UDP消息发送

相当于发短信:不用连接,只需知道对方的地址就可

发送消息

package com.zhang.WLBC.Lesson02.Lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; //不需要连接到服务器
public class UdpClientDemo01 {
public static void main(String[] args) throws Exception{
//1.建立一个socket
DatagramSocket socket=new DatagramSocket();//用来发东西的 此处要抛出异常 //2.建个包
String msg="hello";
new DatagramPacket(msg.getBytes(),0,msg.getBytes().length);//msg.getByte 变成数组 //发送给谁
InetAddress localhost=InetAddress.getByName("localhost");
int port=9090;
DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);//msg.getByte 变成数组
//数据 数据长度的起始 要发给谁 //3.发送包(通过socket发送包)
socket.send(packet); //4.关闭资源
socket.close();// 包不用关
}
}

接收消息

package com.zhang.WLBC.Lesson02.Lesson03;

import java.net.DatagramPacket;
import java.net.DatagramSocket; //服务器端要开放端口,其实还是好比要等待客户端的连接
public class UdpServerDemo01 {
public static void main(String[] args) throws Exception{
//开放端口
DatagramSocket socket=new DatagramSocket(9090);
//接收数据包
byte[] buffer=new byte[1024];
DatagramPacket packet=new DatagramPacket(buffer,0,buffer.length); socket.receive(packet);//阻塞接收(随时等待接收) System.out.println(packet.getAddress());//输出包裹从哪来的
System.out.println(packet.getData());// [B@45ee12a7 data是一个byte,要转为String(new一个string),见下一行
System.out.println(new String(packet.getData(),0,packet.getLength()));//得到包裹的内容
//关闭连接
socket.close();
}
}

实现聊天

循环发送消息

package com.zhang.WLBC.Lesson02.Lesson03.chat;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress; //两者互为发送者和接收者
public class UdpSenderDemo01 {
public static void main(String[] args) throws Exception{
DatagramSocket socket=new DatagramSocket(8888); //准备数据,聊天,需要从控制台读取(System.in)
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in ));
while (true) {
String data = reader.readLine();//读取一行
byte[] dates = data.getBytes();//转换成数据,因为data是不可读的,要转换为字节
DatagramPacket packet = new DatagramPacket(dates, 0, dates.length, new InetSocketAddress("localhost", 6666));//这里需要数据,所以要准备数据
socket.send(packet);
if (data.equals("bye")) {
break;
}
}
socket.close(); }
}

循环接收消息

package com.zhang.WLBC.Lesson02.Lesson03.chat;

import java.net.DatagramPacket;
import java.net.DatagramSocket; public class UdpReceiveDemo01 {
public static void main(String[] args) throws Exception{
DatagramSocket socket=new DatagramSocket(6666); //实现循环接收
while (true){
//准备接收包裹
byte[] container=new byte[1024];
DatagramPacket packet=new DatagramPacket(container,0,container.length);
socket.receive(packet);////这个packet需要一个地方去放置它,所以需要一个准备接收的包裹
//接收过来的消息还得读一下
//断开连接(接收的数据为bye的时候)
byte[] data=packet.getData();
String receiveData=new String(data,0,data.length);//读取接收到的消息
System.out.println(receiveData);
if (receiveData.equals("bye")){
break;
} }
socket.close();
}
}

UDP多线程在线咨询

两个人都可以是发送方,也都可以是接收方

java学习之旅(day.18)的更多相关文章

  1. Java学习之旅开篇:运行机制及环境搭建

    在写这篇博客之前,我想对自己进行简单概括:我从事软件开发工作已经三年多了,并且一直在从事.NET相关项目的开发.为什么突然间想学习Java呢?有以下几个原因: 1. 开发程序三年多来,已经对.NET相 ...

  2. Java学习之旅基础知识篇:面向对象之封装、继承及多态

    Java是一种面向对象设计的高级语言,支持继承.封装和多态三大基本特征,首先我们从面向对象两大概念:类和对象(也称为实例)谈起.来看看最基本的类定义语法: /*命名规则: *类名(首字母大写,多个单词 ...

  3. 第一篇,java学习之旅

    在java的这座殿堂中,我才刚刚推开了大门,就像是在岔路口找到了一条,走向前进java大门的路. 下面是一些java算法的问题 第一题: package project.model; import j ...

  4. Java学习之旅(一):探索extends

    鄙人为兴趣爱好,0基础入门学习Java,有些心得想法,记录于此,与君分享. 然毕竟新手,学识尚浅,错误之处,希望多多指正批评,也是对我最大的帮助! 前言:本篇文章,主要讨论在子类继承父类之后,一些继承 ...

  5. Java学习之旅基础知识篇:数组及引用类型内存分配

    在上一篇中,我们已经了解了数组,它是一种引用类型,本篇将详细介绍数组的内存分配等知识点.数组用来存储同一种数据类型的数据,一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然 ...

  6. Java学习之旅基础知识篇:数据类型及流程控制

    经过开篇对Java运行机制及相关环境搭建,本篇主要讨论Java程序开发的基础知识点,我简单的梳理一下.在讲解数据类型之前,我顺便提及一下Java注释:单行注释.多行注释以及文档注释,这里重点强调文档注 ...

  7. 我的java学习之旅--一些基础

    (因为我粗略学过C,C++,Python,了解过他们的一些语法,所以为了使得java的入门更为顺畅,便会忽略一些和C语法相类似的地方,着重点明一些java自己的特色之处.也减轻一下自己写文字的负担.) ...

  8. Java学习之旅(二):生病的狗1(逻辑推导)

    前言:本篇文章属于个人笔记,例化了一些代码,不知是否合理,请指教. 中午看到一位同学的面试题,觉得很烧脑,烧脑不能一个人烧,要大家一起烧. 村子中有50个人,每人有一条狗.在这50条狗中有病狗(这种病 ...

  9. java学习之旅

    jar文件其实就是一个压缩包,里面包含很多class文件(一个class文件是一个类的字节码).方便在网络上传输.可以规定版本号,更容易进行版本控制. var只能在方法内使用,不能用于定义成员变量. ...

  10. 面向对象编程(OOP)的五大特征-java学习之旅(1)

    这是Alan Kay关于第一个成功的面向对象语言SmallTalk的总结: 1.所有的东西都是对象.可将对象想象成一种新型的变量:它保存着数据,但是可要求它对自身进行操作,理论上讲,可从要解决的问题身 ...

随机推荐

  1. #组合计数,容斥定理#U136346 数星星

    题目 天上的繁星一闪一闪的,甚是好看.你和你的小伙伴们一起坐在草地上,欣赏这美丽的夜景. 我们假定天上有\(n\)颗星星,它们排成一排,从左往右以此编号为1到\(n\),但是天上的星星实在太多了,你和 ...

  2. OpenHarmony 状态变量更改通知:@Watch 装饰器

    @Watch 应用于对状态变量的监听.如果开发者需要关注某个状态变量的值是否改变,可以使用 @Watch 为状态变量设置回调函数. 说明: 从 API version 9 开始,该装饰器支持在 Ark ...

  3. 等个有“源”人|OpenHarmony 成长计划学生挑战赛报名启动

    OpenAtom OpenHarmony(以下简称"OpenHarmony)开源开发者成长计划-解决方案学生挑战赛(以下简称"本大赛"或"成长计划学生挑战赛&q ...

  4. 快速加入Health Kit,一文了解审核流程

    HUAWEI Health Kit是为华为生态应用打造的基于华为帐号和用户授权的运动健康数据开放平台. 在获取用户授权后,开发者可以使用Health Kit提供的开放能力获取运动健康数据,基于多种类型 ...

  5. Viu联合华为HMS生态,共创影音娱乐新体验

    华为HMS生态携手流媒体平台Viu,为海外消费者打造精品移动娱乐应用体验,并助力提升流量变现能力.Viu在中东非.东南亚等16个国家及地区提供广告合作和付费会员服务,支持优质视频内容高清点播和直播.自 ...

  6. Qt使用https协议发送带参数的post请求

    背景: 现在公司项目需要做一个检测更新的功能,通过访问后台接口,判断是否需要更新. 后台接口是 https 协议的,接口需要post请求,需要带参数,来判断是哪个软件需要做检测更新的操作. 客户端软件 ...

  7. openGauss数据库源码解析——慢SQL检测

    openGauss 数据库源码解析--慢 SQL 检测 慢 SQL 检测的定义: 基于历史 SQL 语句信息进行模型训练,并用训练好的模型进行 SQL 语句的预测,利用预测结果判断该 SQL 语句是否 ...

  8. TeamViewer 9发布-在Linux下安装运行

    TeamViewer 9发布-在Linux下安装运行 来源:Linux中国  作者:未知 关注我们:    这篇指南介绍了怎么样在 RedHat. CentOS. Fedora 和 Debian. U ...

  9. redis 简单整理——内存的优化[二十七]

    前言 简单介绍一下内存的优化. 正文 Redis所有的数据都在内存中,而内存又是非常宝贵的资源.如何优化内存的使用一直是Redis用户非常关注的问题.本节深入到Redis细节中,探索内存优化的技巧. ...

  10. 论文记载:FRAP:Learning Phase Competition for Traffic Signal Control

    ABSTRACT 一个为早晨的交通训练好的模型可能不适用于下午的交通,因为交通流可能被逆转,导致非常不同的状态表示.本文基于交通信号控制中相位冲突的直观原理,提出了一种新的设计方案FRAP:当两个交通 ...