Java学习--网络编程
目录
一、网络的基本模型
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
需要详细了解
下面是
二、基于TCP 协议的网络编程
首先我们要了解一下
在
有新兴趣的可以往这边走https://blog.csdn.net/whuslei/article/details/6667471
在计算机网络通信中,我们需要找到具体的程序,通常使用
端口号范围
接下来我们看一下
套接字:用于主机的
着这种端点成为套接字。
服务器端:
客户端:
废话不多说,我们先来搭建一个服务器端和客户端

package com.demo.tcp; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 服务器端 * @author Administrator * */ public class ServerDemo { private ServerSocket server; private Socket socket; private int port = 8888; //构造函数中初始化服务器 public ServerDemo() { // TODO Auto-generated constructor stub try { //这里利用构造方法初始化服务器,我这里只传了一个参数,所以本机相当于服务器 server = new ServerSocket(port); System.out.println("服务器初始化完成..."); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("服务器初始化失败"); } } //服务器需要做的事 public void server(){ //因为服务器不能关,所以需要写个死循环来监听客户端的链接 while(true){ try { //监听客户端的链接,客户端链接进来程序才会继续执行 socket = server.accept(); System.out.println("客户端:"+socket); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { //启动服务器 new ServerDemo().server(); } }

package com.demo.tcp; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; /** * 客户端 */ public class ClickDemo { private Socket socket; private String host = "localhost"; private int port = 8888; //客户端构造方法里连接服务器 public ClickDemo() { // TODO Auto-generated constructor stub try { //客户端初始化需要设定服务器的ip(由于我这里是在同一台机器上,所以host指定的是本地),port端口需要与服务器的端口一致才能连接上 socket = new Socket(InetAddress.getByName(host), port); System.out.println("链接成功"); } catch (IOException e) { // TODO Auto-generated catch block System.err.println("链接超时"); } } public static void main(String[] args) { //启动客户端 new ClickDemo(); } }
服务器和客户端链接之后都会有一个
在我看来,套接字相当于通信的工具,我们可以通过这个通信工具来收发信息
继续查看
则是我们用来收发信息的方法。
接下来我们写一个简单的信息传输实例吧

package com.demo.tcp; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; /** * 客户端 */ public class ClickDemo { private Socket socket; private String host = "localhost"; private int port = 8888; //客户端构造方法里连接服务器 public ClickDemo() { // TODO Auto-generated constructor stub try { //客户端初始化需要设定服务器的ip(由于我这里是在同一台机器上,所以host指定的是本地),port端口需要与服务器的端口一致才能连接上 socket = new Socket(InetAddress.getByName(host), port); System.out.println("链接成功"); } catch (IOException e) { // TODO Auto-generated catch block System.err.println("链接超时"); } } public void send(String context){ try { OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); pw.println(context); pw.flush(); System.out.println("发送成功"); } catch (IOException e) { e.printStackTrace(); System.out.println("发送失败"); } } public static void main(String[] args) { //启动客户端 new ClickDemo().send("HelloWord"); } }

package com.demo.tcp; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * 服务器端 * @author Administrator * */ public class ServerDemo { private ServerSocket server; private Socket socket; private int port = 8888; //构造函数中初始化服务器 public ServerDemo() { // TODO Auto-generated constructor stub try { //这里利用构造方法初始化服务器,我这里只传了一个参数,所以本机相当于服务器 server = new ServerSocket(port); System.out.println("服务器初始化完成..."); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("服务器初始化失败"); } } //服务器需要做的事 public void server(){ //因为服务器不能关,所以需要写个死循环来监听客户端的链接 while(true){ try { //监听客户端的链接,客户端链接进来程序才会继续执行 socket = server.accept(); System.out.println("客户端:"+socket); InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String re = br.readLine(); System.out.println(re); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { //启动服务器 new ServerDemo().server(); } }
三、基于UDP 协议的网络通信
同样,我们先了解一下什么是UDP通信吧
它是一个简单的面向数据报的传输层协议
既然
所以
大致的传输过程如上。
具体的传输流程请看下图
如图所示,我们可以得到一个结果,那就是客户端和服务都是公用的。简单来说就是一个程序既可以成为客户端,
也可以成为服务器端,所以没有
我们来看一下
查看
查看
综上所述,端口和
废话不多说,先写一个
package com.demo.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Date; /** * UDP客户端 * @author Administrator * */ public class UDPClient { private DatagramPacket packet = null; private DatagramSocket socket = null; //客户端程序端口 private int port = 8888; //客户端需发送的数据 private byte [] b = null; //服务器ip private InetAddress address = null; public UDPClient(){ try { socket = new DatagramSocket(); //将字符串装换成InetAddress类型 address = InetAddress.getByName("localhost"); System.out.println("客户端初始化成功"); } catch (SocketException e) { e.printStackTrace(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 发送数据的方法 */ public void send (){ String date = new Date()+""; b = date.getBytes(); System.out.println(date); //将数据打包成一个DatagramPacket报文的格式 packet=new DatagramPacket(b, b.length, address, port); try { //以报文的方式发送数据包 socket.send(packet); } catch (IOException e) { e.printStackTrace(); } } /** * 单报文内的文件发送完了关闭这个Socket通信 */ public void close(){ if(packet!=null){ socket.close(); } } public static void main(String[] args) { UDPClient udpClient = new UDPClient(); for(int i =0;i<10;i++){ udpClient.send(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } udpClient.close(); } }
package com.demo.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; /** * 服务端 * @author Administrator * */ public class UDPServer { private DatagramSocket socket = null; private DatagramPacket packet = null; private int port = 8888; private byte [] b = null; public UDPServer(){ try { socket = new DatagramSocket(port); //每次接收的文件大小 b = new byte[4096]; System.out.println("服务器初始化成功"); //创建一个DatagramPacket对象接收的长度为4096字节,接收到b数组中。 packet = new DatagramPacket(b, b.length); } catch (SocketException e) { e.printStackTrace(); } } /** * 接收方法 */ public void resive(){ try { if(!socket.isClosed()){ socket.receive(packet); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } byte[] data = packet.getData(); String s = new String(data); for(int i =0;i<10;i++){ System.out.println(s); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { new UDPServer().resive(); } }
通过观察代码我们可以知道
顾名思义一个是发信息,一个是收信息。而且发送与接收都是以报文的方式进行的。
PS:由于
四、基于TCP/IP 建立的协议
如果计算机网络按
我们知道
所以我们需要有一套规范(协议
客户端要同时向另一个客户端发送多个报文,并且不同的报文需要对方的客户端做不同的事情,那么我们就需要在报文的头部添加一个唯一识别的信息。
也就是我们所说的协议。同样这套协议也可以是我们自定义的,也可以使用现有的协议。
目前
TCP:FTP 文件传输协议
HTTP 超文本传输协议
SMTP 邮件发送协议
UDP:DNS
TFTP 简单文件传送协议
还有许多协议这里就不列举了。
五、总结
在
在网络这一块,所有的计算机都需要遵循这些协议,若不遵循这些网络信息传输协议,那网络将会发生错乱。作为一名开发人员,如果不嫌麻烦
的话,可以自定义一套自己用的通信协议。但是,在实际开发中,为了保证效率,我们一般会使用相对比较成熟的协议来通信。在选择
通信的时候,我们需要考虑下传输数据的大小,考虑应用的场景。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!