网络编程:UDP TCP
1 网络编程入门
1.1概述
网络编程:在网络通信协议下,不同计算机运行的程序,可以进行数据传输。
1.2三要素
IP地址:设备在网络中的地址,是唯一的标识。
端口:应用程序在设备中唯一的标识。
协议:数据在网络中传输的规则,常见的协议有UDP协议和TCP协议。
1.2.1 IP地址
IP:全称“互联网协议地址”,也称IP地址。是分配给上网设备的数字标签。常见的ip分类为:ip4和ip6
ip4有四个字节,共有256x256x256x256=4,294,967,296种取值。然而ip地址的需求量越来越大,ip4模式下ip总数总是有限的,因此有了ip6.ip6采用128位地址长度,分成8组。
常用命令
ipconfig:查看本机ip地址
ping IP地址:检查网络是否连通
特殊ip地址:
127.0.0.1:是回送地址也称本地回环地址,可以表示本机的ip地址,一般用来测试使用
为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用。
InetAddress address=InetAddress.getByName("DESKTOP-7EKUN48");//参数可以是主机名或者ip
System.out.println("获取IP地址:"+address.getHostAddress());
System.out.println("获取主机名:"+ address.getHostName());
1.2.2 端口
端口:应用程序在设备中唯一的标识。
端口号:用两个字节表示的整数,它的取值范围是0-65535.其中0-1023之间的端口用于一些知名的网络服务或者应用。我们自己使用1024以上的端口号就可以了。
注意:一个端口号只能被一个应用程序使用。
1.2.3 协议
协议:计算机网络中,连接和通信的规则被称为网络通信协议
UDP协议:
用户数据报协议(User Datagram Protocol)
UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64k,数据不安全,容易丢失数据。
TCP协议:
传输控制协议(Transmission Control Protocol)
TCP协议是面向连接的通信协议。
速度慢,没有大小限制,数据安全。
2 UDP通信程序
2.1 UDP发送数据
1、创建发送端的DatagramSocket对象
2、创建数据,并把数据打包
3、调用DatagramSocket的方法发送数据
4、释放资源
public class Client {
public static void main(String[] args) throws Exception{
//1、找码头
DatagramSocket ds=new DatagramSocket();
//2、打包礼物
/*
DatagramPacket(byte buf[], int length, InetAddress address, int port)
参数分别表示:打包的数据,数据长度,发送的Ip,端口
*/
String s="送给老丈人的礼物";
byte[] bytes=s.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
//3、把礼物给码头
ds.send(dp);
//4、付钱走羊
ds.close();
}
}
2.2 UDP接收数据
1、创建接收端的DatagramSocket对象
2、创建一个箱子,用于接收数据
3、调用DatagramSocket的方法接收数据并将数据放入箱子中
4、解析数据包,并把数据在控制台显示
5、释放资源
/**
* UDP协议:面向无连接
* 1、先运行接收端,再运行发送端
* 2、如果接收端在启动之后没有接收到数据,那么会死等(阻塞)
* 3、在接收数据的时候,需要调用getLength方法,表示接收到了多少字节
*/
public class Server {
public static void main(String[] args) throws Exception {
//1、找码头-------端口号表示是从哪个端口接收的(因为客户端将数据送到10000端口上了,所以要从该端口获得)
DatagramSocket ds=new DatagramSocket(10000);
//2、拿新箱子
/*
DatagramPacket(byte buf[], int length)
接收到的数据 数据长度
*/
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
//3、新箱子装礼物
ds.receive(dp);//如果接收不到数据,会在这一行阻塞
//4、老丈人从新箱子拿礼物
//打印string类型的接收内容 从0到接收的最后一个字符
System.out.println(new String(dp.getData(),0,dp.getLength()));
//5、拿完走羊
ds.close();
}
}
2.3 UDP通信程序练习(聊天室)
要求:
1、UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束。
2、UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收。
public class Client {
public static void main(String[] args) throws IOException {
Scanner scanner=new Scanner(System.in);
while(true){
String data=scanner.nextLine();
if (data.equals("886")){
System.out.println("已停止传送数据");
break;
}
byte[] bytes = data.getBytes();
DatagramSocket ds=new DatagramSocket();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.1.16"),10000);
ds.send(dp);
ds.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10000);
while (true) {
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
}
//ds.close(); 不需要关闭 一直开启
}
}
2.4 UDP三种通信方式
2.4.1 单播
以上UDP所有例子都是与一台服务器进行通信。属于单播。
2.4.2 组播
组播地址:224.0.0.0 ~ 239.255.255.255。其中224.0.0.0 ~ 224.0.0.255 为预留的组播地址,我们使用224.0.1.0以上的地址即可。
public class Client {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
String data="hello 组播";
byte[] bytes = data.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("224.0.1.0"),10000);
ds.send(dp);
ds.close();
}
public class Server {
public static void main(String[] args) throws IOException {
MulticastSocket ms=new MulticastSocket(10000);
DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
//把当前计算机绑定组播地址,表示添加到这一组中
ms.joinGroup(InetAddress.getByName("224.0.1.0"));
ms.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
ms.close();
}
}
2.4.3 广播
广播地址:255.255.255.255
public class Client {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
String s="hello 广播";
byte[] bytes = s.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("255.255.255.255"),10000);
ds.send(dp);
ds.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10000);
DatagramPacket dp=new DatagramPacket(new byte[1024],1024);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
ds.close();
}
}
3 TCP通信程序
3.1 TCP通信原理
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象。
通信之前要保证连接已经建立。
通过Socket产生IO流来进行网络通信。
//TCP 发送端
public class Client {
public static void main(String[] args) throws Exception {
//1、创建一个socket对象
//Socket(String host, int port) 要连接的服务器ip,端口
Socket socket=new Socket("192.168.1.16",10000);
//2、获取一个io流写数据
OutputStream out=socket.getOutputStream();
out.write("hello tcp".getBytes());
//3、释放资源
socket.close();
out.close();
}
}
//TCP 接收端
public class Server {
public static void main(String[] args) throws IOException {
//1、创建socket对象
ServerSocket ss=new ServerSocket(10000);
//2、等待客户端连接
Socket accept=ss.accept();//等不到发送端就会阻塞
//3、获取输入流对象
InputStream in=accept.getInputStream();
int len=0;
while((len=in.read())!=-1){
System.out.print((char)len);
}
//4、释放资源
in.close();
ss.close();
}
}
3.2 TCP通信程序练习
要求:
1、客户端:发送数据,接收服务器反馈
2、服务器:接收数据,给出反馈
public class Client {
public static void main(String[] args) throws Exception{
Socket socket=new Socket("192.168.1.16",10000);
OutputStream os=socket.getOutputStream();
os.write("hello TCP".getBytes());
os.flush();
socket.shutdownOutput();//仅仅关闭输出流,并写一个输出标记,对socket没有影响
InputStream is = socket.getInputStream();
int len;
while((len=is.read())!=-1){
System.out.print((char)len);
}
is.close();
os.close();
socket.close();
}
}
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10000);
Socket accept=ss.accept();
InputStream is=accept.getInputStream();
int len=0;
while((len=is.read())!=-1){
System.out.print((char)len);
}
OutputStream os=accept.getOutputStream();
os.write("who are you?".getBytes());
os.flush();
os.close();
is.close();
accept.close();
ss.close();
}
}
3.3 TCP通信程序练习(文件上传)
要求:
1、客户端:将本地文件上传到服务器。接收服务器的反馈。
2、服务器:接收客户端上传的文件,上传完毕之后给出反馈。
public class Client {
public static void main(String[] args) throws Exception{
Socket socket=new Socket("192.168.1.16",10000);
//本地流 读取本地文件
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("01_inetAddress/ClientDir/feder.jpg"));
//网络流 写到服务器
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
int len;
byte[] data=new byte[1024];
while((len=bis.read(data))!=-1){
bos.write(data,0,len);//通过网络写到服务器
}
//给服务器结束标记
socket.shutdownOutput();
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line="";
while((line=br.readLine())!=null){
System.out.println(line);
}
bis.close();
socket.close();
}
}
public class Server {
public static void main(String[] args) throws Exception{
ServerSocket ss=new ServerSocket(10000);
Socket accept = ss.accept();
//网络流 从客户端读取
BufferedInputStream bis=new BufferedInputStream(accept.getInputStream());
//本地流 写到文件夹中
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("01_inetAddress/ServerDir/copy_feder.jpg"));
int len;
byte[] data=new byte[1024];
while((len=bis.read(data))!=-1){
bos.write(data,0,len);
}
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bw.write("上传成功");
bw.newLine();
bw.flush();
bos.close();
accept.close();//socket关闭 网络流一定关闭 不用手动bis.close()
ss.close();
}
}