如何学习 Java 中的 Socket 编程,进行网络通信

Socket编程是网络编程的核心技术之一,它使得不同主机之间可以进行数据通信。Java提供了丰富的网络编程API,使得编写网络应用程序变得相对简单和直观。本文将详细讲解如何学习Java中的Socket编程,并通过示例代码展示如何实现网络通信。

一、Socket编程基础

1.1 什么是Socket?

Socket是一种网络通信的端点,包含IP地址和端口号。在网络通信中,一个Socket实例代表一个网络连接的一个端点,通过两个Socket实例(客户端和服务器)可以实现网络通信。

1.2 TCP和UDP

Socket编程主要分为两种类型:基于TCP(Transmission Control Protocol)的Socket编程和基于UDP(User Datagram Protocol)的Socket编程。

  • TCP:面向连接的协议,提供可靠的、顺序正确的、无差错的数据传输。常用于需要高可靠性的场景。
  • UDP:无连接的协议,提供不保证可靠性的数据传输。适用于对传输速度要求较高,但对可靠性要求较低的场景。

二、Java中的Socket类

2.1 Java Socket API

Java提供了以下主要的Socket编程类:

  • java.net.Socket:实现客户端Socket,负责与服务器建立连接并进行通信。
  • java.net.ServerSocket:实现服务器Socket,负责监听客户端的连接请求。
  • java.net.DatagramSocket:实现UDP协议的Socket,用于发送和接收数据报文。
  • java.net.DatagramPacket:表示UDP的数据报文。

三、基于TCP的Socket编程

3.1 客户端Socket编程

客户端通过java.net.Socket类实现。步骤如下:

  1. 创建Socket对象,并连接到服务器。
  2. 获取输入输出流,用于发送和接收数据。
  3. 关闭Socket连接。

示例代码:

import java.io.*;
import java.net.*;public class TCPClient {public static void main(String[] args) {String serverName = "localhost"; // 服务器地址int port = 8080; // 服务器端口try {// 连接到服务器Socket client = new Socket(serverName, port);// 获取输出流,发送数据到服务器OutputStream outToServer = client.getOutputStream();DataOutputStream out = new DataOutputStream(outToServer);out.writeUTF("Hello from " + client.getLocalSocketAddress());// 获取输入流,接收服务器返回的数据InputStream inFromServer = client.getInputStream();DataInputStream in = new DataInputStream(inFromServer);System.out.println("Server says " + in.readUTF());// 关闭连接client.close();} catch (IOException e) {e.printStackTrace();}}
}
3.2 服务器Socket编程

服务器通过java.net.ServerSocket类实现。步骤如下:

  1. 创建ServerSocket对象,并绑定到指定端口。
  2. 调用accept()方法,等待客户端连接。
  3. 获取输入输出流,用于接收和发送数据。
  4. 关闭Socket连接。

示例代码:

import java.io.*;
import java.net.*;public class TCPServer {public static void main(String[] args) {int port = 8080; // 监听端口try {// 创建服务器SocketServerSocket serverSocket = new ServerSocket(port);while (true) {// 等待客户端连接Socket server = serverSocket.accept();// 获取输入流,接收客户端发送的数据DataInputStream in = new DataInputStream(server.getInputStream());System.out.println("Client says " + in.readUTF());// 获取输出流,发送数据到客户端DataOutputStream out = new DataOutputStream(server.getOutputStream());out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress());// 关闭连接server.close();}} catch (IOException e) {e.printStackTrace();}}
}

四、基于UDP的Socket编程

4.1 客户端Socket编程

客户端通过java.net.DatagramSocketjava.net.DatagramPacket类实现。步骤如下:

  1. 创建DatagramSocket对象。
  2. 创建DatagramPacket对象,封装要发送的数据。
  3. 调用send()方法发送数据。
  4. 调用receive()方法接收数据。
  5. 关闭DatagramSocket。

示例代码:

import java.net.*;public class UDPClient {public static void main(String[] args) {String serverName = "localhost"; // 服务器地址int port = 8080; // 服务器端口try {// 创建客户端SocketDatagramSocket clientSocket = new DatagramSocket();// 发送数据byte[] sendData = "Hello from client".getBytes();InetAddress IPAddress = InetAddress.getByName(serverName);DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);clientSocket.send(sendPacket);// 接收数据byte[] receiveData = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);clientSocket.receive(receivePacket);String modifiedSentence = new String(receivePacket.getData());System.out.println("FROM SERVER: " + modifiedSentence);// 关闭连接clientSocket.close();} catch (Exception e) {e.printStackTrace();}}
}
4.2 服务器Socket编程

服务器通过java.net.DatagramSocketjava.net.DatagramPacket类实现。步骤如下:

  1. 创建DatagramSocket对象,并绑定到指定端口。
  2. 创建DatagramPacket对象,用于接收数据。
  3. 调用receive()方法接收数据。
  4. 创建DatagramPacket对象,封装要发送的数据。
  5. 调用send()方法发送数据。
  6. 关闭DatagramSocket。

示例代码:

import java.net.*;public class UDPServer {public static void main(String[] args) {int port = 8080; // 监听端口try {// 创建服务器SocketDatagramSocket serverSocket = new DatagramSocket(port);while (true) {// 接收数据byte[] receiveData = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);serverSocket.receive(receivePacket);String sentence = new String(receivePacket.getData());System.out.println("RECEIVED: " + sentence);// 发送数据InetAddress IPAddress = receivePacket.getAddress();int clientPort = receivePacket.getPort();String capitalizedSentence = sentence.toUpperCase();byte[] sendData = capitalizedSentence.getBytes();DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, clientPort);serverSocket.send(sendPacket);}} catch (Exception e) {e.printStackTrace();}}
}

五、Java Socket编程中的常见问题

5.1 端口冲突

端口冲突是指多个程序尝试绑定到同一个端口,这会导致端口不可用。解决方法是确保每个程序使用不同的端口,或者检查端口是否被占用。

5.2 数据传输中的阻塞

Socket通信是阻塞式的,意味着读写操作会阻塞线程直到数据被完全传输。可以使用多线程或者非阻塞I/O(NIO)来解决这个问题。

5.3 数据粘包与拆包

在TCP协议中,由于数据是以流的形式发送,接收方可能会一次接收到多个数据包(粘包)或一个数据包被分成多次接收(拆包)。解决方法是在数据包中添加长度字段,或者使用定界符来标识每个数据包的边界。

六、高级话题:多线程和NIO

6.1 多线程Socket编程

在实际应用中,服务器通常需要同时处理多个客户端的连接。可以使用多线程来实现,每个客户端连接由一个线程处理。

示例代码:

import java.io.*;
import java.net.*;public class MultiThreadedTCPServer {public static void main(String[] args) {int port = 8080; // 监听端口try {// 创建服务器SocketServerSocket serverSocket = new ServerSocket(port);System.out.println("Server started on port " + port);while (true) {// 等待客户端连接Socket clientSocket = serverSocket.accept();System.out.println("New client connected: " + clientSocket.getInetAddress());// 创建一个新的线程处理客户端请求new ClientHandler(clientSocket).start();}} catch (IOException e) {e.printStackTrace();}}
}class ClientHandler extends Thread {private Socket clientSocket;public ClientHandler(Socket socket) {this.clientSocket = socket;}public void run() {try {// 获取输入流,接收客户端发送的数据DataInputStream in = new DataInputStream(clientSocket.getInputStream());System.out.println("Client says: " + in.readUTF());// 获取输出流,发送数据到客户端DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());out.writeUTF("Thank you for connecting!");// 关闭连接clientSocket.close();} catch (IOException e) {e.printStackTrace();}}
}
6.2 非阻塞I/O(NIO)

Java NIO(New I/O)提供了非阻塞的网络通信方式,可以提高服务器的性能和扩展性。NIO中的核心组件包括Channel、Buffer和Selector。

示例代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class NioTCPServer {public static void main(String[] args) {int port = 8080; // 监听端口try {// 创建选择器Selector selector = Selector.open();// 打开服务器Socket通道ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(port));serverSocketChannel.configureBlocking(false);serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("Server started on port " + port);while (true) {// 等待事件selector.select();// 获取发生事件的SelectionKeyIterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();if (key.isAcceptable()) {// 接受连接ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();SocketChannel socketChannel = serverChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {// 读取数据SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(256);socketChannel.read(buffer);String message = new String(buffer.array()).trim();System.out.println("Client says: " + message);// 响应客户端buffer.flip();socketChannel.write(buffer);}}}} catch (IOException e) {e.printStackTrace();}}
}

黑马程序员免费预约咨询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/854833.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java情侣飞行棋系统小程序+H5+微信公众号+APP 源码

&#x1f491;甜蜜互动&#xff0c;共赴云端之旅&#x1f6eb; &#x1f308;一、引言&#xff1a;飞行棋遇上情侣&#xff0c;乐趣翻倍 在繁忙的生活中&#xff0c;情侣们总是渴望找到一种简单而有趣的方式来增进彼此的感情。这时&#xff0c;情侣飞行棋小程序应运而生&#…

视频融合共享平台LntonCVS视频监控管理平台技术方案详细介绍

LntonCVS国标视频综合管理平台是一款以视频为核心的智慧物联应用平台。它基于分布式、负载均衡等流媒体技术进行开发&#xff0c;提供广泛兼容、安全可靠、开放共享的视频综合服务。该平台具备多种功能&#xff0c;包括视频直播、录像、回放、检索、云存储、告警上报、语音对讲…

【C#】汽车租赁系统设计与实现

目的&#xff1a; 设计一个简单的汽车租赁系统&#xff0c;包含以下功能&#xff1a; 添加车辆&#xff1a;用户可以添加新的车辆到系统中&#xff0c;包括车辆的品牌、型号、车牌号、日租金等信息。查找车辆&#xff1a;用户可以通过车牌号或者品牌来查找车辆&#xff0c;并…

编程搭积木的app叫什么:探索积木编程的奥秘与应用

编程搭积木的app叫什么&#xff1a;探索积木编程的奥秘与应用 在数字化时代&#xff0c;编程教育日益受到重视&#xff0c;而积木编程作为一种新颖、有趣的学习方式&#xff0c;正逐渐走进人们的视野。那么&#xff0c;那些让我们通过搭积木来学习编程的app到底叫什么呢&#…

【HarmonyOS NEXT】鸿蒙https请求跳过证书校验

https请求前&#xff0c;进行自签名证书加载 1.运行报错&#xff1a; error:{"code":2300060,"message":"SSL peer certificate or SSH remote key was not OK"}&#xff0c;显示无法校验服务器身份&#xff0c; 2. 导致这个错误码的原因可能有…

MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现

项目场景&#xff1a; 在使用MyBatis&#xff0c;我们经常会遇到这种情况&#xff1a;SELECT两个字段&#xff0c;需要返回一个Map&#xff0c;其中第一个字段作为key&#xff0c;第二个字段作为value。MyBatis的MapKey虽然很实用&#xff0c;但并不能解决这种场景。 问题描述 …

编程大赛的题怎么做:策略、技巧与实战经验

编程大赛的题怎么做&#xff1a;策略、技巧与实战经验 编程大赛&#xff0c;作为一场集智慧、技巧与实战经验于一体的较量&#xff0c;吸引了无数编程爱好者的参与。然而&#xff0c;面对复杂多变的题目和激烈的竞争环境&#xff0c;如何有效地解题并脱颖而出&#xff0c;成为…

【Unity】向量应用:已知入射方向和法向量求反射方向(跳弹系统)

文章目录 已知入射方向和法向量求反射方向已知条件解题思路代码范例 已知入射方向和法向量求反射方向 已知条件 已知入射向量v1和法向量n&#xff08;OB&#xff09;&#xff0c;求反射向量v2&#xff0c;上述向量均为单位向量。 解题思路 设 AO为 v1 &#xff1b;OB为 n …

ABAP随笔记

1:/nsxi_monitor查看接口日志 2:内表数据拼接 2.1、给内表加一个空行并修改他的值 APPEND INITIAL LINE TO GT_ALV ASSIGNING FIELD-SYMBOL(<FS>) .2.2、将内表数据拼接在一行 CONCATENATE LINES

外贸独立站做了没效果怎么办

如果外贸独立站做了但没有达到预期的效果&#xff0c;可以考虑以下几个方面来进行优化和改进&#xff1a; 1. 优化网站内容&#xff1a;确保网站内容高质量、专业且符合目标市场的需求。更新内容以保持网站的活跃度和相关性。 2. 搜索引擎优化(SEO)&#xff1a;对网站进行SEO…

实验13 BGP路径选择

实验13 BGP路径选择 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 与域内路由不同&#xff0c;域间路由更加注重策略&#xff0c;而不是技术。在域内进行选路&#xff0c;可以使用路由算法计算出到达目的子网的最短路径&#xff1b;而在…

如何完美解决 Oracle Database 19c 安装程序 - 第7步(共8步)卡住,半小时都不动

&#x1f680; 如何完美解决 Oracle Database 19c 安装程序 - 第7步&#xff08;共8步&#xff09;卡住&#xff0c;半小时都不动 摘要 在安装 Oracle Database 19c 时&#xff0c;很多用户会在第7步&#xff08;共8步&#xff09;遇到卡住的问题&#xff0c;尤其是安装程序长…

行业模板|DataEase应用平台对接大屏模板推荐

DataEase开源数据可视化分析工具于2022年6月发布模板市场&#xff08;https://templates-de.fit2cloud.com&#xff09;&#xff0c;并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板&#xff0c;方便用户根据…

Spring框架的最新进展:2023年Spring Boot和Spring Cloud功能更新

引用 Spring框架的最新动态&#xff1a;2023年Spring Boot与Spring Cloud功能升级 Spring框架作为Java开发领域的重要技术之一&#xff0c;一直致力于简化开发流程和提高开发效率。2023年&#xff0c;Spring Boot和Spring Cloud两大核心组件再次迎来功能升级&#xff0c;为开…

【杂记-浅谈虚拟类型终端VTY用户界面】

一、VTY概述 VTY是Virtual Teletype Terminal的缩写&#xff0c;指的是路由器或交换机的远程登录的虚拟端口。这些虚拟端口允许用户通过Telnet或SSH协议连接到网络设备进行管理和维护操作。 user-interface vty 是华为设备中的一个重要配置命令&#xff0c;主要用于配置虚拟类…

哪个充电宝牌子好用又实惠?盘点四大平价充电宝分享

在当今快节奏的生活中&#xff0c;充电宝已成为我们日常生活中不可或缺的一部分。然而&#xff0c;面对市场上琳琅满目的充电宝品牌和型号&#xff0c;许多消费者误以为选择容量越大、价格越高的充电宝就是最好的选择。实际上&#xff0c;买充电宝并不是一味追求高容量和高价格…

深入解析知识付费平台的核心功能模块:满足个性化学习需求的数字化教育新星

在数字化学习的大潮中&#xff0c;知识付费平台已成为教育行业的一颗新星&#xff0c;它以满足用户需求为核心&#xff0c;提供便捷高效的学习渠道。该平台汇聚了各类专业知识&#xff0c;覆盖职业技能、生活兴趣和人文社科等多个领域&#xff0c;满足不同用户的学习需求。同时…

laravel Blade 指令的趣味性

首先,我们通过几个要点来解释 Blade 引擎的工作原理。 您选择一个 Blade 模板进行渲染。引擎使用一系列正则表达式来解析和编译模板。该引擎生成一个普通的 PHP 文件并将其写入磁盘(以便将其缓存以供将来渲染)。包含 PHP 文件并使用输出缓冲区来捕获生成的 HTML。该过程中最…

【scrapy】爬虫,从429状态码说起

许久未爬&#xff0c;发现爬不动了&#xff0c;哈哈哈&#xff0c;记录下这次失败的爬取经历 问题描述 针对这样的一个网站&#xff1a; https://www.farfetch.cn/cn/shopping/women/dresses-1/items.aspx?page1&view96&sort3 需求&#xff1a; 1.需要爬取列表页…

TOP10!YashanDB斩获广东省优秀信创产品与解决方案双料荣誉

近日&#xff0c;2024广东软件风云榜结果出炉&#xff0c;表彰为广东软件产业和数字经济、新型工业化发展作出突出贡献的企业、企业家、优秀产品等。深算院崖山数据库系统 YashanDB荣获广东省“2024年优秀信息技术应用创新产品TOP10”和“2024年优秀信息技术应用创新行业应用解…