java网络编程:Socket
java Socket 编程基于 B/S
简单的TCP网络程序
TCP通信分析图解
-
【服务端】启动,创建ServerSocket对象,等待连接。
-
【客户端】启动,创建Socket对象,请求连接。
-
【服务端】接收连接,调用accept方法,并返回一个Socket对象。
-
【客户端】Socket对象,获取OutputStream,向服务端写出数据。
-
【服务端】Scoket对象,获取InputStream,读取客户端发送的数据。
B:
class StudentClient{ public static void main(String[] args) throws IOException { //获取主机地址 InetAddress address = InetAddress.getByName("127.0.0.1"); //创建Socket对象 Socket socket = new Socket(address, 10086); //推送数据,建立输出流 OutputStream outputStream = socket.getOutputStream(); //字节流加载数据 outputStream.write("你好,服务器".getBytes()); //释放资源 outputStream.close(); socket.close(); } }
S:
class StudentServer{ public static void main(String[] args) throws IOException { //构建socket服务端 ServerSocket serverSocket = new ServerSocket(10086); //等待客服端链接 System.out.println("准备就绪,等待客服端链接"); //侦听客服端数据 Socket socket = serverSocket.accept();//一直侦听,阻塞进程,直到有消息 //读取数据 InputStream inputStream = socket.getInputStream(); //h缓冲 byte[] bytes = new byte[1024]; int len;//长度 while ((len=inputStream.read(bytes))!=-1){ System.out.println(new String(bytes,0,len)); } //释放资源 inputStream.close(); serverSocket.close(); } }
B/S优化:管道流
//Socket编程客户端 public class JavaSocketClientG { public static void main(String[] args) throws IOException { Socket socket = null; InetAddress ServerIP=null; OutputStream outputStream=null; try { //1.要知道服务器端口号 ServerIP = InetAddress.getByName("127.0.0.1"); //端口号 int port = 9999; //2.创建一个Socket连接 socket = new Socket(ServerIP, port); //3.发送消息IO流 //c outputStream = socket.getOutputStream(); outputStream.write("你好,我发送信息过来了!!!".getBytes()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (outputStream != null) { outputStream.close(); } if (socket != null) { socket.close(); } } } }
//Socket编程服务端 public class JavaServiceSocketG { public static void main(String[] args) { ServerSocket serverSocket=null; Socket accept=null; InputStream inputStream=null; ByteArrayOutputStream byteArrayOutputStream=null; try { //client----发送数据(输出流)------------(输入)-【管道流处理数据】-(输出)------接收数据(输入流)------server //1.服务端的有一个端口 serverSocket= new ServerSocket(9999); //2.监听客户端发过来的信息 accept= serverSocket.accept(); //3.读取客户端的信息(信息对于服务器管道是写入-就是输入流) inputStream= accept.getInputStream(); //4.管道流获取数据处理 byteArrayOutputStream= new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len= inputStream.read(buffer))!=-1){ byteArrayOutputStream.write(buffer,0,len); } System.out.println(byteArrayOutputStream.toString()); } catch (IOException e) { e.printStackTrace(); }finally { try { if(serverSocket!=null){ serverSocket.close(); } if (accept!=null){ accept.close(); } if (inputStream!=null){ inputStream.close(); } if (byteArrayOutputStream!=null){ byteArrayOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
UDP网络编程
概述
类DatagramSocket
和DatagramPacket
实现了基于 UDP 协议网络程序。
UDP数据报通过数据报套接字DatagramSocket
发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
DatagramPacket
对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。如同发快递包裹一样。
简单的UDP网络程序
UDP通信分析图解
-
DatagramSocket与DatagramPacket
-
建立发送端,接收端
-
建立数据包
-
调用Socket的发送、接收方法
-
关闭Socket
建立UDP接收端
-
建立udp socket服务,因为是要接收数据,必须要明确一个端口号。
-
创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据.
-
使用socket服务的receive方法将接收的数据存储到数据包中。
-
通过数据包的方法解析数据包中的数据。
-
关闭资源
接受端:
public static void main(String[] args) throws IOException { System.out.println("接收端启动......"); /* * 建立UDP接收端的思路。 * 1,建立udp socket服务,因为是要接收数据,必须要明确一个端口号。 * 2,创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据. * 3,使用socket服务的receive方法将接收的数据存储到数据包中。 * 4,通过数据包的方法解析数据包中的数据。 * 5,关闭资源 */ //1,建立udp socket服务。 DatagramSocket ds = new DatagramSocket(10000); while(true){ //2,创建数据包。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); //3,使用接收方法将数据存储到数据包中。 ds.receive(dp);//阻塞式的。 //4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+port+":"+text); } //5,关闭资源。 // ds.close(); }
发送端:
public static void main(String[] args) throws IOException { System.out.println("发送端启动......"); //1,udpsocket服务。使用DatagramSocket对象。 DatagramSocket ds = new DatagramSocket(8888); //2,将要发送的数据封装到数据包中。 String str = "udp传输演示:哥们来了!"; //使用DatagramPacket将数据封装到的该对象包中。 byte[] buf = str.getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000); //3,通过udp的socket服务将数据包发送出去。使用send方法。 ds.send(dp); //4,关闭资源。 ds.close(); }
文件上传:copy
客户端:
package Demo1.JavaSe.javasocket; import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; //文件上传操作 public class JavaDemo2 { //客户端 public static void main(String[] args) throws Exception { //client----发送数据(输出流)------------(输入)-【管道流处理数据】-(输出)------接收数据(输入流)------server // 1.创建Socket连接对象:创建它对应的对接的iP和端口。。。 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9999); //2.创建一个输出流 OutputStream outputStream = socket.getOutputStream(); //3.传入文件需要文件流 //读取文件 FileInputStream myFileStream = new FileInputStream(new File("src/a123.jpg")); //写出文件 byte[] buffer = new byte[1024]; int len; while ((len=myFileStream.read(buffer))!=-1){ outputStream.write(buffer,0,len); } //同知服务器我传输完成 socket.shutdownOutput(); System.out.println("上传成功"); //接受服务器发过来的 InputStream isput = socket.getInputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer2 = new byte[1024]; int len2; while ((len2=isput.read(buffer2))!=-1){ byteArrayOutputStream.write(buffer2,0,len2); } //打印服务端的确认消息 System.out.println(byteArrayOutputStream.toString()); //关闭资源 byteArrayOutputStream.close(); isput.close(); myFileStream.close(); outputStream.close(); socket.close(); } } class TestInetAddress{ public static void main(String[] args) throws Exception { InetAddress address = InetAddress.getByName("www.baidu.com"); System.out.println(address.getHostAddress());//返回 IP 地址字符串(以文本表现形式) System.out.println(address.getHostName());//获取此 IP 地址的主机名 System.out.println(address.isReachable(1000));//测试是否可以达到该地址 } }
服务器:
package Demo1.JavaSe.javasocket; import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class JavaDemo2Server { //服务端 public static void main(String[] args) throws IOException { //1.创建服务。 ServerSocket serverSocket = new ServerSocket(9999); //2.监听客户端消息 Socket accept = serverSocket.accept();//阻塞式监听 //3.获取输入流 InputStream iput = accept.getInputStream(); //4.文件输出 FileOutputStream receive = new FileOutputStream(new File("src/receive.jpg")); byte[] buffer = new byte[1024]; int len; //输入流 把信息读取到 缓冲区 返回字节数 while ((len = iput.read(buffer))!=-1){ receive.write(buffer,0,len); } System.out.println("接受成功"+len+"字节数"); //反馈给客户端 OutputStream outputStream = accept.getOutputStream(); outputStream.write("来自服务器的确认消息!".getBytes()); //5.关闭 receive.close(); iput.close(); serverSocket.close(); } }
文件上传分析图解
-
【客户端】输入流,从硬盘读取文件数据到程序中。
-
【客户端】输出流,写出文件数据到服务端。
-
【服务端】输入流,读取文件数据到服务端程序。
-
【服务端】输出流,写出文件数据到服务器硬盘中。
优化实现:
文件上传:
public class FileUpload_Server { public static void main(String[] args) throws IOException { System.out.println("服务器 启动..... "); // 1. 创建服务端ServerSocket ServerSocket serverSocket = new ServerSocket(6666); // 2. 循环接收,建立连接 while (true) { Socket accept = serverSocket.accept(); /* 3. socket对象交给子线程处理,进行读写操作 Runnable接口中,只有一个run方法,使用lambda表达式简化格式 */ new Thread(new Runnable() { try ( //3.1 获取输入流对象 BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //3.2 创建输出流对象, 保存到本地 . FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg"); BufferedOutputStream bos = new BufferedOutputStream(fis);) { // 3.3 读写数据 byte[] b = new byte[1024 * 8]; int len; while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } //4. 关闭 资源 bos.close(); bis.close(); accept.close(); System.out.println("文件上传已保存"); } catch (IOException e) { e.printStackTrace(); } }).start(); } } }
信息回写分析图解
前四步与基本文件上传一致.
-
【服务端】获取输出流,回写数据。
-
【客户端】获取输入流,解析回写数据。
public class FileUpload_Server { public static void main(String[] args) throws IOException { System.out.println("服务器 启动..... "); // 1. 创建服务端ServerSocket ServerSocket serverSocket = new ServerSocket(6666); // 2. 循环接收,建立连接 while (true) { Socket accept = serverSocket.accept(); /* 3. socket对象交给子线程处理,进行读写操作 Runnable接口中,只有一个run方法,使用lambda表达式简化格式 */ new Thread(new Runnable { try ( //3.1 获取输入流对象 BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //3.2 创建输出流对象, 保存到本地 . FileOutputStream fis = new FileOutputStream(System.currentTimeMillis() + ".jpg"); BufferedOutputStream bos = new BufferedOutputStream(fis); ) { // 3.3 读写数据 byte[] b = new byte[1024 * 8]; int len; while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } // 4.=======信息回写=========================== System.out.println("back ........"); OutputStream out = accept.getOutputStream(); out.write("上传成功".getBytes()); out.close(); //================================ //5. 关闭 资源 bos.close(); bis.close(); accept.close(); System.out.println("文件上传已保存"); } catch (IOException e) { e.printStackTrace(); } }).start(); } } }
客户端实现:
public class FileUpload_Client { public static void main(String[] args) throws IOException { // 1.创建流对象 // 1.1 创建输入流,读取本地文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg")); // 1.2 创建输出流,写到服务端 Socket socket = new Socket("localhost", 6666); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); //2.写出数据. byte[] b = new byte[1024 * 8 ]; int len ; while (( len = bis.read(b))!=-1) { bos.write(b, 0, len); } // 关闭输出流,通知服务端,写出数据完毕 socket.shutdownOutput(); System.out.println("文件发送完毕"); // 3. =====解析回写============ InputStream in = socket.getInputStream(); byte[] back = new byte[20]; in.read(back); System.out.println(new String(back)); in.close(); // ============================ // 4.释放资源 socket.close(); bis.close(); } }
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
Java入门到入坟
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南