Socket介绍及使用Java实现socket通信

news2024/11/27 10:23:53

一、Socket概述

        Socket(套接字)是计算机网络编程中用于实现网络通信的一种机制。它提供了一种编程接口,允许应用程序通过网络进行数据传输,实现不同主机之间的通信。

        Socket可以看作是一种抽象的概念,用于描述网络通信的端点。它包含了通信所需的各种参数和状态信息,以便应用程序能够通过它进行数据的发送和接收。

Socket的主要特点包括以下几个方面:

  1. 通信协议:Socket可以基于不同的通信协议进行数据传输,例如TCP/IP、UDP等。
  2. 通信模型:Socket可以支持不同的通信模型,如面向连接的流式Socket(如TCP)和无连接的数据报式Socket(如UDP)。
  3. 客户端-服务器模型:Socket通常用于实现客户端-服务器模型,其中客户端应用程序通过Socket与服务器进行通信。
  4. 端口号:Socket通过端口号来标识应用程序的通信端口,以便不同的应用程序能够同时在同一台主机上进行网络通信。
  5. API接口:Socket提供了一组API接口,供应用程序进行Socket编程,包括建立连接、发送数据、接收数据、关闭连接等操作。

        Socket编程可以在不同的编程语言中进行,如C、C++、Java、Python等,通过调用相应的Socket API来实现网络通信功能。在Socket编程中,通常涉及以下几个步骤:

  1. 创建Socket:使用Socket API创建一个Socket对象,指定协议类型和通信模式。
  2. 绑定端口:将Socket绑定到本地的IP地址和端口号上。
  3. 监听连接请求(仅服务器端):对于服务器端,调用Socket API监听来自客户端的连接请求。
  4. 建立连接(仅客户端):对于客户端,调用Socket API与服务器端建立连接。
  5. 数据传输:通过Socket发送和接收数据。
  6. 关闭连接:在通信结束后,关闭Socket连接。

        Socket编程可以用于各种网络应用,如Web服务器、邮件服务器、聊天应用、游戏等。它为应用程序提供了灵活、可靠和高效的网络通信方式。

二、Java实现socket通信

1. 使用TCP连接

使用TCP通信,它使用java.net.Socket创建了一个Socket对象。Socket类通常用于TCP通信。

(1)服务端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try {
            // 创建ServerSocket对象,指定监听的端口号
            ServerSocket serverSocket = new ServerSocket(12345);

            System.out.println("等待客户端连接...");

            // 监听客户端的连接请求
            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端已连接");

            // 获取输入流和输出流 输入流和输出流是通过socket对象来进行数据传输的。
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            String message;

            while (true) {
                // 读取客户端发送的信息
                message = in.readLine();

                if (message.equalsIgnoreCase("exit")) {
                    // 如果接收到终止标志,退出循环
                    break;
                }

                System.out.println("收到客户端消息:" + message);

                // 发送响应给客户端
                out.println("已收到你的消息:" + message);
            }

            // 关闭连接
            clientSocket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(2)客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try {
            // 创建Socket对象,指定服务端的IP地址和端口号
            Socket socket = new Socket("127.0.0.1", 12345);

            // 获取输入流和输出流 输入流和输出流是通过socket对象来进行数据传输的。
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            // 从控制台读取用户输入
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String message;

            while (true) {
                System.out.println("请输入要发送的信息(输入 'exit' 退出):");
                message = reader.readLine();

                if (message.equalsIgnoreCase("exit")) {
                    // 如果用户输入 'exit',发送终止标志给服务端并退出循环
                    out.println("exit");
                    break;
                }

                // 将用户输入的信息发送给服务端
                out.println(message);

                // 接收服务端的响应并打印
                String response = in.readLine();
                System.out.println("服务端响应:" + response);
            }

            // 关闭连接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试结果:

 2. 使用UDP连接

使用UDP通信,使用java.net.DatagramSocket创建了一个DatagramSocket对象。DatagramSocket类通常用于UDP通信。

(1)服务端

package socket.UDP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;

public class UDPClient {
    public static void main(String[] args) {
        try {
            // 创建DatagramSocket对象
            DatagramSocket socket = new DatagramSocket();

            InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
            int serverPort = 12345;

            // 从控制台读取用户输入
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String message;

            while (true) {
                System.out.println("请输入要发送的信息(输入 'exit' 退出):");
                message = reader.readLine();

                if (message.equalsIgnoreCase("exit")) {
                    // 如果用户输入 'exit',退出循环
                    break;
                }

                byte[] sendData = message.getBytes();

                // 创建发送数据的DatagramPacket对象
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, serverPort);

                // 发送数据
                socket.send(sendPacket);

                byte[] receiveData = new byte[1024];

                // 创建接收数据的DatagramPacket对象
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

                // 接收服务端的响应
                socket.receive(receivePacket);

                // 将接收到的数据转换为字符串并打印
                String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("服务端响应:" + response);
            }

            // 关闭Socket连接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(2)客户端

package socket.UDP;

import java.io.IOException;
import java.net.*;

public class UDPServer {
    public static void main(String[] args) {
        try {
            // 创建DatagramSocket对象,并指定监听的端口号
            DatagramSocket socket = new DatagramSocket(12345);
            System.out.println("等待客户端连接...");

            byte[] receiveData = new byte[1024];

            while (true) {
                // 创建接收数据的DatagramPacket对象
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

                // 接收客户端发送的数据
                socket.receive(receivePacket);

                // 获取客户端的IP地址和端口号
                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();

                // 将接收到的数据转换为字符串
                String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("收到客户端消息:" + message);

                if (message.equalsIgnoreCase("exit")) {
                    // 如果接收到终止标志,退出循环
                    break;
                }

                // 构造发送数据的字节数组
                String response = "已收到你的消息:" + message;
                byte[] sendData = response.getBytes();

                // 创建发送数据的DatagramPacket对象
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);

                // 发送响应给客户端
                socket.send(sendPacket);
            }

            // 关闭Socket连接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试结果:

 

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

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

相关文章

性能监控软件的软件特色有哪些?

性能监控软件是一种专门用于监测和分析系统性能的软件工具。它可以帮助开发人员、运维人员和系统管理员追踪系统的性能瓶颈,优化系统性能,提供稳定可靠的服务,那性能监控软件的软件特色有哪些? 实时监控:性能监控软件可…

3、CCesium 第一个地图

1、将下载的CCsium库解压到指定目录如D:/install,里面有几个文件 bin:导出的dll examples:一个简单的示例 include:ccesium和第三方库的头文件 lib:搜索cceisum库的一些信息 share:一些说明 我们主要用…

allatori-JAVA代码混淆工具

Allatori是第二代Java混淆器,它为您的知识产权提供全方位的保护。 虽然大多数第二代混淆器都能提供值得信赖的保护,但我们在Allatori中开发了一些额外的功能,使代码的反向工程几乎不可能。 Allatori不仅仅是混淆,它还能最大限度…

为什么你感觉中层管理一直闲着没事干?

点击下方“JavaEdge”,选择“设为星标” 第一时间关注技术干货! 免责声明~ 切记,任何文章不要过度深思(任何东西都无法经得起审视,因为这世上没有同样的成长环境,也没有同样的认知水平同时也「没有适用于所…

eNSP的使用

目录 配置路由器 DHCP——动态主机配置协议 工作过程: 第一种场景——PC首次获取IP地址的情况 第二种场景——pc(客户都)再次获取IP地址的情况 DHCP配置: Telnet 搭建好图后 1.看广播域(路由器有几个接口就有几…

在树莓派上搭建web站点并发布互联网上线【无需公网IP】

文章目录 概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS设置 Apache Web 服务器测试 web 站点安装静态样例站点将web站点发布到公网安装 Cpolar内网穿透cpolar进行token认证生成cpolar随机域名网址生成cpolar二级子域名将参数保存到cpolar配置文件中测试修改后配置文件配…

JUC--CompletableFuture下

对计算速度进行选用 import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit;public class Test4 {public static void main(String[] args) {CompletableFuture<String> a CompletableFuture.supplyAsync(() -> {try { TimeUnit.SE…

list和vector容器的插入与访问操作区别

文章目录 list插入元素和vector插入元素对比案例vector的做法list优化的做法为什么时间复杂度相同还会有性能差异 std::list和std::vector是C中的两种常见数据结构&#xff0c;它们在不同的使用场景下各有优势。 std::vector的内部实现是动态数组&#xff0c;它在连续的内存块…

weak_ptr 智能指针的使用

目录 一&#xff0c;weak_ptr 变量的定义 二&#xff0c;expired() 成员函数 三&#xff0c;lock() 成员函数 四&#xff0c;use_count() 成员函数 五&#xff0c;为什么要用 weak_ptr 一&#xff0c;weak_ptr 变量的定义 weak_ptr 对象的构造有3种方法&#xff1a; 1&am…

Python基础综合案例-数据可视化(折线图)

今天给大家带来的是Python综合实战开发的数据可视化操作 通过python实现对数据的分析、可视化 数据来源: 系统开发环境&#xff1a; 操作系统&#xff1a;win11 Python解释器版本&#xff1a;python3.10 开发工具&#xff1a;Pychram Python内置模块&#xff1a;pyecharts 1…

HarmonyOS/OpenHarmony应用开发-Stage模型应用/组件级配置

在开发应用时&#xff0c;需要配置应用的一些标签&#xff0c;例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。图标和标签通常一起配置&#xff0c;可以分为应用图标、应用标签和入口图标、入口标签&#xff0c;分别对应app.json5配置文件…

二进制算术运算

当两个数码表示数量大小时&#xff0c;可以进行加减乘除等算术运算。 一&#xff1a;两数绝对值之间的运算 加法运算&#xff1a; 二进制的每一位只有0和1两个数&#xff0c;低位向高位的进位关系是“逢二进一”&#xff0c;所以中的每一位的运算规则为&#xff1a; 减法运算&…

【无标题】企业数字化转型需要什么样的生产力工具?

前言 企业的数字化转型是一个很大的话题&#xff0c;从宏观到微观&#xff0c;涉及到目标、战略、方案、路径、计划、组织、流程等方方面面。我们今天聊一个非常落地非常具体的问题——企业数字化转型需要什么样的生产力工具&#xff1f; 需要哪些类型的生产力工具&#xff1…

论文摘要写什么内容

一、引言 论文摘要是我们在学术研究领域当中最常见的一种形式&#xff0c;它扮演着关键的角色&#xff0c;为研究者在学术圈子中传播自己思想提供了重要途径。然而&#xff0c;如何编写一份既简洁而易读&#xff0c;又充满深度和洞察的摘要呢&#xff1f;这篇文章将提供一些基…

Scala特证/特质【6.7 特质(Trait)】

Scala特证/特质【6.7 特质&#xff08;Trait&#xff09;】 6.7 特质&#xff08;Trait&#xff09;Java 的接口接口的作用抽象类的作用 6.7.1 特质声明6.7.2 特质基本语法6.7.3 特质叠加6.7.4 特质叠加执行顺序6.7.5 特质自身类型6.7.6 特质和抽象类的区别 &#xff08;任意内…

Lua学习笔记:面向对象的实现

前言 本篇在讲什么 Lua中的面向对象的实现 本篇适合什么 适合初学Lua的小白 本篇需要什么 对Lua语法有简单认知 依赖Sublime Text编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &…

MySQL数据库基础(三):多表查询,子查询,开窗函数

十一、多表查询&#xff08;重点、难点&#xff09; 表与表之间的关系 在SQL语句中&#xff0c;数据表与数据表之间&#xff0c;如果存在关系&#xff0c;一般一共有3种情况&#xff1a; ① 一对一关系&#xff08;高级&#xff09; 比如有A、B两张表&#xff0c;A表中的每一…

多肽试剂:143120-27-8,Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide

试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a; 环肽试剂Cyclo(-D-Tyr-Arg-Gly-Asp-Cys(carboxymethyl)-OH) sulfoxide&#xff0c;陕西新研博美生物科技有限公司多肽合成、定制多肽、同位素标记肽、人工胰岛素、磷酸肽、生物素…

Python split()函数使用详解,Python分割字符串

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 split 1、不指定分隔符2、分隔符的类型3、指定分隔次数4、分隔的结果 split() 可…

你真的不想知道怎么用ai绘画图片生成图片吗?

亲爱的二次元迷们&#xff0c;你是否曾经梦想过能够画出自己心中的二次元角色&#xff0c;让他们跃然纸上、生动活泼地展现在世人面前&#xff1f;但是&#xff0c;面对空白的画板和一支笔&#xff0c;我们有时会感到无从下手&#xff0c;毫无艺术细胞可言。不要失望&#xff0…