本帖最后由 小石姐姐 于 2018-4-25 15:56 编辑
网络编程_基于UDP及TCP协议的数据传输
* 网络编程:
* 通过我们编写的程序让两个不同的设备可以进行交互,可以进行数据的传输,
* 两个设备本身是无法传输数据的,通过软件或程序才可以进行不同设备之间的传输,
* 说到网络编程,就不得不说Socket(套接字)
*Socket(套接字):
* 写在不同设备间的程序也可称之为Socket
* 我们所说的网络编程也可称为Socket编程或套接字编程
* 不同程序之间的数据传输就是不同Socket之间的传输
* 通信:数据在两个Socket之间的是通过IO流进行的;
*
* 通信三要素:
* 1. IP地址:InterAddress 现在的IP地址用32为2进制数表示,也就是4个字节
* 设备在网络中的地址
* ipconfig 命令在windows的dos命令行可以显示:
* 网卡/ip地址
* 在dos命令行中ip地址使用的是点分十进制法,来表示的,可以更方便的去记忆和修改ip地址
* //命令为 ipconfig
* 1.1 IP分为 :
* * 网络地址
* * 主机地址(内网地址)
* 这两个地址 确保了全球网络的唯一性,但是4字节(IPV4)的网络地址,相对于现在来说已经太小了,
* 因此有了现在的IPv6 它是IPv4的六倍,也就是16个字节
* 1.2 IP地址根据用途及安全级别的不同还分为:
* 1.公共地址(可以通过Internet直接访问)
* 2.私有地址(内部网地址,局域网地址)
*
* 2.端口号: 用于标识进程的逻辑地址,不同进程的表示
* 网络编程:就是两个设备之间的软件进行交互
* 每个软件运行都要有一个进程,端口号指的就是这个进程的地址,设备中有很多网络程序,因此要指定一个
* 具体的 网络程序,所以需要进程的地址,也就是端口号.
* 3.协议
* 其实就是一种规则和规范
* 有很多的网络协议:后期会接触两种协议
* 1.UOP协议
* 2.TCP协议:通过三次握手完成连接,是可靠协议;
*
* UDP协议:
* 将数据源和目的地封装成数据包,不需要建立连接了;
* 每个数据包的大小限制在64k;无连接,是不可靠的协议;
* 不需要建立连接,速度快;
* TCP协议:
* 建立连接,行成传输数据的通道;在连接中进行大数据量传输;
* 通过三次握手完成连接,是可靠协议;
* 必须建立连接,效率会稍低
域名和主机名一样:
1.网络上叫域名
2.局域网中叫主机名
----------------------------------------------------
>>>>>> UDP 协议接收 / 发送 数据 <<<<<<
UDP协议收发注意事项:
* 1.端口号错误,数据可以正常发出,不会抛出异常,但是接受不到数据
* 2.接受端口号不可以重名(多个程序运行时)
* 重复会报错:"java.net.BindException: Address already in use: Cannot bind"
* 意思为端口号已绑定;
* 第一个运行此端口可程序不会报错,后运行该端口的程序会报错
* 3.因此在设定接受端端口号时,避免跟其它程序的端口号冲突;
*
* 1.数据发送时,接收端的IP,端口都在数据报包中
* 2.接受数据时,接收端口号在数据接收套接字中
* 3.发送的时候会通过IP找到接受端设备,在统过端口号,将数据送到指定的程序
* 4.想后去发送端的信息需要通过解析接受包,使用数据报包的方法获取;
------------
案例:
1.数据接收
2.数据发送
------------
>>>>>>> 接收端程序
package com.jobday12;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/*
* 使用UDP协议接受数据:
* 1.创建接受端Socket对象
* 2.接受数据
* 3.解析数据
* 4.输出数据
* 5.释放资源
*
* DatagramSocket 类的接收数据方法
* 对象名.receive(DatagramPacket dp);
* 1.发送数据
* 2.使用该方法时,如果内有数据传进来,程序会一直在该处 < 阻塞 >;
*
*
* DatagramPacket 类的获取方法:
* InetAddress getAddress()
* //返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。
************************
* 问题: 不明白 *
* 1.接受数据时获取发送端的IP *
* 2.发送数据时获取接受端的IP *
************************
byte[] getData():
//获取接受的数据
int getLength()
//返回将要发送或接收到的数据的长度。
int getPort()
//返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。(获取接受或发送端的端口,相对当前程序)
*/
public class 接受端_UDP协议接受数据 {
public static void main(String[] args) throws IOException {
//1.创建接受端Socket对象
//创建指定端口号的数据接收对象(与发送端指定的接受端口号要一致)
DatagramSocket ds = new DatagramSocket(888);
//2.接受数据
//定义接受数据的容器
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
//接受数据
ds.receive(dp);//此处会阻塞,等待数据传入
//3.解析数据
//获取发送端的IP地址
InetAddress address = dp.getAddress();
//获取接受数据的实际长度
int leng = dp.getLength();
//获取数据
bys = dp.getData();
//4.输出数据
System.out.println("发送端IP: "+address);
System.out.println("接受数据长度: "+leng);
System.out.println("接受到的数据 : "+new String(bys,leng));
//5.释放资源
}
}
-------------
>>>>>> 发送端程序
package com.jobday12;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/*
*使用UDP协议发送数据
* 1.创建发送端Socket对象
* 2.创建数据并打包
* 3.发送数据
* 4.释放资源
*
*数据发送接收类:
*
* DatagramSocket 类: 此类表示用来发送和接受数据,基于UDP协议的(此类表示用来发送和接收数据报包的套接字。)
*
* 1. DatagramSocket():创建Socket对象并随即分配端口号(随机给自己分配一个端口号)
* 2. DatagramSocket(int port):创建Socket对象并制定端口号(int port,指的是自己的端口号)
* 如果是创建发送端对象的话使用方法1就行(随机生成就行),因为是发送数据因此自己的端口号知不知道都行
* 如果是接受数据,就要制定自己的端口号,因为发送端发送数据是指定了端口,因此接受端就要有指定的端口号(不可以随机生成)
*
* 数据报包类:
* DatagramPacket : 此类表示数据报包
* 构造:
* DatagramPacket(byte[] buf, int length, InetAddress address, int port)
* //构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
* byte[] buf : 数据
* int length : 数据包中数据的长度(字节数组中数据的实际长度)
* InetAddress address :目的地设备的IP地址
* int port : 接收端端口号
*
*/
public class 发送端_UDP协议发送数据 {
public static void main(String[] args) throws IOException {
//1.创建发送端Socket对象
DatagramSocket ds = new DatagramSocket();
//2.创建数据并打包
//要发送的数据
byte[] bys = "hello,udp,im coming!".getBytes();
//数长度
int leng = bys.length;
//接收端IP对象 ,此处是通过本机主机名,开获取的IP对象,因为接受端也在次电脑上(实际中获取的是接受断点的IP对象)
InetAddress address = InetAddress.getByName("USERCHI-D484R2Q");
//接受端口
int port = 888; //此处随机定义了一个接收端接受程序的端口号
//创建数据包报对象,打包数据
DatagramPacket dp = new DatagramPacket(bys,leng,address,port);
//3.发送数据
ds.send(dp);//此方法发送数据是以个DatagramPacket类的对象(也就是数据报包)
InetAddress add = dp.getAddress();
System.out.println(add);
//4.释放资源
ds.close();
}
}
----------------------------------------------------------------------------
>>>>>>>>> TCP 协议 发送_接受数据 <<<<<<<<<<<<<<<
>>>>>>>> 发送端
package com.jobday12;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 使用TCP协议送数据
创建发送端Socket对象(创建连接)
获取输出流对象
发送数据
释放资源
注意:
没有接收端的话,运行发送端,就会报错,连接异常
java.net.ConnectException
*/
public class TCP协议_发送数据 {
public static void main(String[] args) throws IOException {
//创建发送端Socket对象(创建连接)
Socket s = new Socket(InetAddress.getByName("USERCHI-D484R2Q"),10086);
// 获取输出流对象
OutputStream os = s.getOutputStream();
//发送数据
String str = "hello tcp,im comming!!!";
os.write(str.getBytes());
//释放资源
s.close();
}
}
--------------------------
>>>>>>>>> 接收端
package com.jobday12;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/*
使用TCP协议接受数据
创建接受端Socket对象
监听(阻塞)
获取输入流对象
获取数据
输出数据
释放资源
Socket 是客户端套接字
接收端要用 ,服务端Socket
服务端为: ServerSocket(int port) //构造
方法:
ServerSocket(int port)
Socket accept() //侦听并接受到此套接字的连接.获取一个客户端套接字
//ServerSocket 本身没有读取功能,因此需要获取一个
//Socket,利用的它的读取功能获取发送端的数据
通过获取到的Socket对象的方法可以获取发送端的IP地址
*/
public class TCP协议_接受端 {
public static void main(String[] args) throws IOException {
//创建接受端Socket对象
ServerSocket ss = new ServerSocket(10086);
//监听(此处会一直阻塞,知道有)
Socket s = ss.accept();//一直等待客户端发来的链接,收到数据后会返回一个Socket对象
//通过Socket获得数据和客户端的数据
InetAddress inetAddress = s.getInetAddress();
System.out.println(inetAddress.getHostAddress());
//获取发送端的IP地址
//获取输入流对象
InputStream is = s.getInputStream();
//获取数据
byte[] bys = new byte[1024];
int len;
len = is.read(bys);
//输出数据
System.out.println(new String(bys,0,len));
//释放资源
is.close();//关闭输入流
//服务器端不需要关闭
}
}
|
|