【网络编程--UDP、TCP】
目录
- 1.UDP
- 1.1 网络编程
- 1.2 怎么查看进程的端口号
- 1.2 InetAddress
- 1.3 端口协议:
- 1.4 UDP协议
- 1.5 UDP 数据交互代码演示
- 2.TCP
- 2.1 TCP 三次握手
- 2.2 TCP四次挥手
- 2.2 基本代码演示
- 2.3 TCP发送端 接收端 使用多种方式实现字符串的传输和就收
- 2.4 TCP 实现图片的传输,优化后结合多线程
- 3 注意点
1.UDP
1.1 网络编程
网络编程
意义:能在不同的电脑上,传输数据
网络三要素:ip 端口,协议
问题:访问百度首页,本质上是访问百度的服务器
ipv4是点分十进制,如192.168.23.44 ipv6 冒分十六进制。因为ipv4资源枯竭(255255255*255),使用ipv6进行补充( 很多app也支持ipv6 如支付宝app的首页,手机设置中也可以看到)
1.2 怎么查看进程的端口号
1.第一步:任务管理器 -->详细信息–>查看pid —>飞秋
第二步:查到飞秋的pid后,在cmd执行netstat -ano 通过pid 对应端口
1.2 InetAddress
// static InetAddress getByName(String host)确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址// String getHostName() 获取此IP地址的主机名 //String getHostAddress() 返回文本显示中的IP地址字符串 public class InetAddressDemo {public static void main(String[] args) throws UnknownHostException {
//InetAddress address = InetAddress.getByName("itheima");InetAddress address = InetAddress.getByName("192.168.1.66");//public String getHostName():获取此IP地址的主机名String name = address.getHostName();//public String getHostAddress():返回文本显示中的IP地址字符串String ip = address.getHostAddress();System.out.println("主机名:" + name);System.out.println("IP地址:" + ip);}
}
1.3 端口协议:
端口:
设备上应用程序的唯一标识
端口号: 了解:
用两个字节表示的整数,它的取值范围是065535。其中,01023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败
如果平常使用udp 或者tcp 建议直接使用10000以上的端口---->避免端口冲突
如:443—https 80–>http 3306—>数据库的端口
1.4 UDP协议
无连接通信协议,在通信前不需要建立逻辑连接,所以发送的数据可能丢失,发送数据的时候不管你接不接受得到,发完就不管了,接收端也不会向发送端发送反馈信息。
由于使用UDP协议消耗系统资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输
1.5 UDP 数据交互代码演示
UDP三种通讯方式分别是什么?
单播(一对一) 单播用于两个主机之间的端对端通信 组播(多对一) 组播用于对一组特定的主机进行通信 广播(一对多)
广播用于一个主机对整个局域网上所有主机上的数据通信
发送数据
/*** 127.0.0.1本机回送地址,用于测试使用,如网线拔了 ,不存在192.168.12.xxx地址*/
public class ClientDemo {public static void main(String[] args) throws IOException {//1.找码头--找一个快递员DatagramSocket ds = new DatagramSocket();//2.打包礼物//DatagramPacket(byte[] buf, int length, InetAddress address, int port)String s = "送给村长老丈人的礼物";byte[] bytes = s.getBytes();//将ip换成了对象//指定唯一 一个发送的IP,这是单播,(一对一)InetAddress address = InetAddress.getByName("127.0.0.1");int port = 10000;
// 如 包裹,包裹的重量,包裹的地址,包裹的电话号码DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);//3.由码头发送包裹ds.send(dp);//4.付钱走羊ds.close();}
}
接收数据
public class ServerDemo {//注意点://1.要先运行接收端,再运行发送端//2.如果接收端再启动之后,没有接收到数据,那么会死等(阻塞).//3.在接收数据的时候,需要调用一个getLength方法,表示接收到了多少字节public static void main(String[] args) throws IOException {//1.找码头 ---- 表示接收端从10000端口接收数据的.DatagramSocket ds = new DatagramSocket(10000);//2,创建一个新的箱子byte [] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes,bytes.length);//3.接收礼物,把礼物放到新的箱子中System.out.println("-----------接收前----------");ds.receive(dp);System.out.println("------------接收后---------");//4.从新的箱子里面获取礼物byte[] data = dp.getData();// 获得数据的长度int length = dp.getLength();System.out.println(new String(data,0,length));//5.拿完走羊ds.close();}
}
代码的练习
UDP使用组播发送消息:
package com.ww.udp2;import java.io.IOException;
import java.net.*;/*** 组播*/
public class Client {public static void main(String[] args) throws IOException {DatagramSocket ds = new DatagramSocket();String s="大家好本组的成员们";byte[] bytes = s.getBytes();int port=10000;InetAddress address = InetAddress.getByName("224.0.1.2");//设置组播的地址,向在一个组的接收端发消息DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,address,port);ds.send(dp);ds.close();}
}
UDP使用组播接收消息:
package com.ww.udp2;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;public class ServiceZu {public static void main(String[] args) throws IOException {MulticastSocket ms = new MulticastSocket(10000);byte [] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length);//白名单,只能接收这些IP发来的消息InetAddress address = InetAddress.getByName("224.0.1.2");InetAddress address2= InetAddress.getByName("224.0.1.3");InetAddress address3= InetAddress.getByName("224.0.1.4");ms.joinGroup(address);//将ms加入本组的组播地址,这样只要是加入这个组的接收端都能接收到发送端发来的信息ms.joinGroup(address2);//将ms加入本组的组播地址,这样只要是加入这个组的接收端都能接收到发送端发来的信息ms.joinGroup(address3);//将ms加入本组的组播地址,这样只要是加入这个组的接收端都能接收到发送端发来的信息ms.receive(dp);byte[] data = dp.getData();int length = dp.getLength();System.out.println(new String(data,0,length));ms.close();}
}
UDP的广播案例代码实现
发送端
package com.ww.udp;import java.io.IOException;
import java.net.*;
import java.util.Scanner;/*** 广播*/
public class Client {public static void main(String[] args) throws IOException {//创建码头DatagramSocket ds = new DatagramSocket();Scanner sc = new Scanner(System.in);while (true) {String s= sc.nextLine();if ("886".equals(s)){break;}byte[] bytes = s.getBytes();//"192.168.12.35"//这里设置的是广播地址,那么这个发送端发送的消息,所有的接收端都能接收,前提是在同一个端口 发送端和接收端要使用同一个端口//为什么要使用同一个端口,就相当于QQ只能发消息给QQ,不能发给微信,每个软件都有自己的端口号,// 并且每个人在电脑上的同一款软件,使用的都是默认的端口号,所以同一款软件,在不同的电脑中使用的端口号是相同的,// 这样就能解释为什么需要端口号相同才能接收到信息了InetAddress address = InetAddress.getByName("255.255.255.255");//创建数据DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,address,10000);ds.send(dp);}ds.close();}
}
接收端
package com.ww.udp;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.concurrent.*;// Base64util.GenerateImage(new String(bytes,0,length),"mz.jpg")
public class Service {public static void main(String[] args) throws IOException {DatagramSocket ds = new DatagramSocket(10000);ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3,10,60,TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//192.168.12.125for (int i=0;i<15;i++) {poolExecutor.submit(//这里使用了线程池实现多线程,多次提交任务new Runnable() {@Overridepublic void run() {Object o =1;synchronized (o){byte [] arr = new byte[1024];DatagramPacket dp = new DatagramPacket(arr,0,arr.length);try {System.out.println("准备接收信息...");ds.receive(dp);//receive()方法会阻塞线程除非接收到数据System.out.println("接收到信息了....");} catch (IOException e) {e.printStackTrace();}//从箱子中获取数据
// byte[] data = dp.getData();int length = dp.getLength();String hostName = dp.getAddress().getHostName();System.out.println("来自"+hostName+"小朋友:"+new String(arr,0,length));}}});}// poolExecutor.shutdown();// ds.close();}
}
2.TCP
2.1 TCP 三次握手
TCP协议:面向连接、通信效率低、数据传输可靠无差错,大小没有限制
了解:
tcp协议建立连接时需要经过三次握手确保连接建立。为什么是三次握手呢?
发送端向接收端发送一个连接信息,然后接收端回馈一个消息给发送端。这里就经过了两次握手了,那么发送端可以确定自己发送的消息接收端可以接收到,但是接收端还不能确定自己反馈的消息有没有被发送端接收到,所以发送端接收到接收端的反馈信息后,还需要向接收端发一条消息告诉接收端它的反馈已经被接收。这样就能确定接收端和发送端互相发的消息都能接收到
2.2 TCP四次挥手
2.2 基本代码演示
public class ServerDemo {public static void main(String[] args) throws IOException {//创建服务器端的Socket对象(ServerSocket)//ServerSocket(int port) 创建绑定到指定端口的服务器套接字ServerSocket ss = new ServerSocket(10000);//Socket accept() 侦听要连接到此套接字并接受它Socket s = ss.accept();//获取输入流,读数据,并把数据显示在控制台InputStream is = s.getInputStream();byte[] bys = new byte[1024];int len = is.read(bys);String data = new String(bys,0,len);System.out.println("数据是:" + data);//释放资源s.close();ss.close();}
}
2.3 TCP发送端 接收端 使用多种方式实现字符串的传输和就收
Client 发送端 发送字符串 读写包含多种方式
package com.ww.tcp;import java.io.*;
import java.net.Socket;
//使用tcp来发送信息,需要经过三次握手
public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1",10000);OutputStream os = socket.getOutputStream();String s= "嗨喽";//第一种方式:-------------------------------------// 使用字节输出流一次写一个字节数组// os.write(s.getBytes());//----------------------------------------------//第二种方式:--------------------------------------------//使用转换流,将字节输出流,转换成字符输出流,一次写一个字符串OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");osw.write(s);osw.flush();//这里需要使用flush()将数据从流冲刷出去,这样才能被服务端接收到数据//因为后面还需要使用到socket所以不能直接使用socket.close,只能使用shutdownOutput(),// 告诉服务端一个介素标记我已经写完,服务端才能展示读到的数据socket.shutdownOutput();//--------------------------------------------------------//使用缓冲流接收服务端回复的消息BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));System.out.println("服务器的回复信息:"+br.readLine());//释放资源socket.close();}
}
Service 接收端 接收字符串 读写包含多种方式
package com.ww.tcp;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class Service {public static void main(String[] args) throws IOException, InterruptedException {ServerSocket ss = new ServerSocket(10000);Socket accept = ss.accept();InputStream is = accept.getInputStream();/*
//第一种方式://读一个字节打印一个字节会出现乱码,因为一个汉字,用utf-8码表一个中文是3个字节,//所以打印一个字节只能乱码int b;while ((b=is.read())!=-1){System.out.print((char) b);}
*//*//第二种方式byte [] bytes = new byte[1024];//len返回读取到的字节长度,一次读取整个字符串个字节,因为几个中文的字节数不可能比1024大,// 这样就能解决字节流读取字符乱码问题int len = is.read(bytes);//一次根据utf-8码表打印所有字节,就不会有乱码了System.out.println("使用字节流接收发送端的中文信息:"+new String(bytes,0,len));
*///第三种方式:使用转化流将字节输入流转换成字符输入流,读取字符InputStreamReader isr = new InputStreamReader(is, "utf-8");int a;while ((a= isr.read())!=-1){//一次读取一个字符System.out.print((char)a);//输出字符串}Thread.sleep(2000);//回馈的时候用休息一下//使用缓冲流回复客户端,告诉客户端我已经接收到消息BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));bw.write("我接收到你的嗨喽了,很高兴认识你!");bw.flush();//这里写完之后为什么没有不用accept调用shutdownOutput(),给客户端传递结束标记//因为下面的accept.close()的close()方法就包含了shutdownOutput(),所以不用再调用shutdownOutput()方法了//释放资源accept.close();ss.close();}
}
2.4 TCP 实现图片的传输,优化后结合多线程
Client 发送端:
package com.ww.tcp;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class Service {public static void main(String[] args) throws IOException, InterruptedException {ServerSocket ss = new ServerSocket(10000);Socket accept = ss.accept();InputStream is = accept.getInputStream();/*
//第一种方式://读一个字节打印一个字节会出现乱码,因为一个汉字,用utf-8码表一个中文是3个字节,//所以打印一个字节只能乱码int b;while ((b=is.read())!=-1){System.out.print((char) b);}
*//*//第二种方式byte [] bytes = new byte[1024];//len返回读取到的字节长度,一次读取整个字符串个字节,因为几个中文的字节数不可能比1024大,// 这样就能解决字节流读取字符乱码问题int len = is.read(bytes);//一次根据utf-8码表打印所有字节,就不会有乱码了System.out.println("使用字节流接收发送端的中文信息:"+new String(bytes,0,len));
*///第三种方式:使用转化流将字节输入流转换成字符输入流,读取字符InputStreamReader isr = new InputStreamReader(is, "utf-8");int a;while ((a= isr.read())!=-1){//一次读取一个字符System.out.print((char)a);//输出字符串}Thread.sleep(2000);//回馈的时候用休息一下//使用缓冲流回复客户端,告诉客户端我已经接收到消息BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));bw.write("我接收到你的嗨喽了,很高兴认识你!");bw.flush();//这里写完之后为什么没有不用accept调用shutdownOutput(),给客户端传递结束标记//因为下面的accept.close()的close()方法就包含了shutdownOutput(),所以不用再调用shutdownOutput()方法了//释放资源accept.close();ss.close();}
}
自定义的Runnable的 实现类 ThreadSocket把需要完成的任务放进run()方法中执行,从而在Server中使用线程池来实现多线程
Server 接收端
package com.ww.tcp2;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class Server {public static void main(String[] args) throws IOException {ServerSocket ss = new ServerSocket(10000);
//192.168.232.1ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, //核心线程数量8, //线程池的总数量60, //临时线程空闲时间TimeUnit.SECONDS, //临时线程空闲时间的单位new LinkedBlockingQueue<>(10), //阻塞队列 自定义阻塞队列的长度为10Executors.defaultThreadFactory(), //创建线程的方式 使用工厂创建线程new ThreadPoolExecutor.AbortPolicy() //任务拒绝策略);while (true) {Socket accept = ss.accept();ThreadSocket ts = new ThreadSocket(accept);//ts是Runnable的实现类//new Thread(ts).start();//实现多线程poolExecutor.submit(ts);//使用自定义的线程池来实现多线程}//ss.close(); 死循环服务器端就不关闭了}
}
3 注意点
注意事项:
accept方法是阻塞的,作用就是等待客户端连接
客户端创建对象并连接服务器,此时是通过三次握手协议,保证跟服务器之间的连接
针对客户端来讲,是往外写的,所以是输出流
针对服务器来讲,是往里读的,所以是输入流
这里的客户端和服务器端都是在内存中的,输入输出都是相对于内存来说的
read方法也是阻塞的
创建客户端对象,创建输入流对象指向文件,每读一次数据就给服务器输出一次数据,输出结束后使用shutdownOutput()方法告知服务端传输结束客户端在关流的时候,还多了一个往服务器写结束标记的动作
最后一步断开连接,通过四次挥手协议保证连接终止
【网络编程--UDP、TCP】相关推荐
- java 网络编程 UDP TCP
网络编程 网络编程主要用于解决计算机与计算机(手机.平板..)之间的数据传输问题. 网络编程: 不需要基于html页面就可以达到数据之间的传输. 比如: feiQ , QQ , 微信.... 网页编程 ...
- JVAV——网络编程UDP/TCP
一: 计算机网络可以实现多台计算机的连接但不同的计算机操作系统和硬件体系结构不同,为了提供通信支持位于同一网络中的计算机必须要遵循一定的规则.目前应用最广泛的是TCP/IP,UDP,ICMP等协议. ...
- 网络编程 udp tcp的使用
111111 /*InetAddress此类表示Internet协议(IP)地址public static InetAddress getByName(String host):确定主机名称的IP地 ...
- python网络编程自学_五分钟搞定Python网络编程实现TCP和UDP连接
Python网络编程实现TCP和UDP连接, 使用socket模块, 所有代码在python3下测试通过. 实现TCP#!/usr/bin/env python3 # -*- coding: utf- ...
- 网络编程及TCP/UDP协议
网络编程 1.1.概述 地球村:你在西安,一个在美国 打电话--连接--接了--通话 TCP 发短信--发完了就完事了--接收 UDP(丢包) 计算机网络: 计算机网络系统就是利用通信设备和线路将地理 ...
- 21天学会Java之(Java SE第十三篇):网络编程、TCP/UDP通信
如今,计算机已经成为人们学习.工作.生活必不可少的工具.人们利用计算机可以和亲朋好友在网上聊天,玩网游或发邮件等,这些功能的实现都离不开计算机网络.计算机网络实现了不同计算机之间的通信,而这些必须依靠 ...
- 网络编程(tcp和udp)
文章目录 网络编程 1 软件结构 2 网络通信协议 2.1 TCP/IP协议参考模型 2.2 TCP与UDP协议 3 网络编程三要素 1.协议 2.IP地址 3.端口号 4 InetAddress类 ...
- 网络编程(TCP、UDP)
一.概述 地球村:也译为世界村(global village),对地球的一种比喻说法.现代科技的迅速发展,缩小了地球上的时空距离,国际交往日益频繁便利,因而整个地球就如同是茫茫宇宙中的一个小村落. J ...
- Java的网络编程【TCP与UDP聊天小程序】
Java的网络编程[TCP与UDP聊天小程序] 1. TCP协议 1.1 传输控制协议(Transmission Control Protocol),是一种**面向连接(全程保持连接)**的协议,类似 ...
- 【网络编程】TCP 网络应用程序开发
[网络编程]TCP 网络应用程序开发 TCP 网络应用程序开发流程 1. TCP 网络应用程序开发流程的介绍 2. TCP 客户端程序开发流程的介绍 3. TCP 服务端程序开发流程的介绍 4. 小结 ...
最新文章
- 心得体悟帖---开解语录2
- delphi编程创建桌面快捷方式
- C#sql语句如何使用占位符
- 一个人的成功取决于晚上的8点至10点--经典语录必读
- Java script第二课
- IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理
- 麦马计算机科学 UBC工程,2020年UBC文书题目
- 封装批量获取键值对数据的方法
- 用枚举法实现单例设计模型
- 关于一些初级ACM竞赛题目的分析和题解(八)
- 1362:家庭问题(family)
- UC/OSII一些小知识
- linux文件空洞与稀疏文件,Linux文件空洞与稀疏文件
- 人口logistic模型公式_最新人口指数增长模型和logistic模型教学文案
- 企业微信与个人微信实现消息互通,用企业微信连接10亿客户
- 【JAVA】-- 字符流(Reader、Writer)
- U8g2库的详细使用
- 岭回归实现鲍鱼年龄预测 MATLAB实现
- 欧科云链接受北京电视台采访:以创新科技助力《反电信网络诈骗法》实施
- Mac OS下fis3 安装教程