您现在的位置是:首页 > 正文

Socket介绍及使用Java实现socket通信 最新发布

2024-02-29 10:27:48阅读 5

一、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();
        }
    }
}

测试结果:

 

网站文章

  • git补充

    git branch不带参数,列出本地的分支git branch -v -a查看所有分支列表,包括本地和远程,带版本信息git remote -v -v 看本地pull和push对应的远程git branch -vv 可以查看本地分支对应的远程分支git checkout  origin/release -b release基于远程releasegit远程仓库地址修改方法有三...

    2024-02-29 10:27:42
  • IDEA故障——无法获取同一个包下的类

    idea开发,突然出现:同一个包下的java代码,突然飘红,出现红色的波浪下划线,错误提示:cannot access com.xx…xx.class。 重启。

    2024-02-29 10:27:12
  • Linux父进程为1怎么kill​​

    linux 杀死进程kill 等用法:kill -9 $(ps -ef | grep process_name | grep -v grep | awk '{print $2}')

    2024-02-29 10:27:06
  • MYSQL基础之函数:子查询分类单行和多行,关联和非关联

    MYSQL基础之函数:子查询分类单行和多行,关联和非关联

    前面聊了一些查询的东西,现在聊SELECT中相对而言最难的一部分—子查询。 子查询指一个查询语句中嵌套在另一个查询语句内部的查询,这个特性从MYSQL4.1开始引入。 SQL中子查询的使用大大增强了S...

    2024-02-29 10:27:01
  • 【洛谷P2839】middle(二分答案)(主席树)

    传送门题解:复习一下常见的trick。求中位数转化为二分答案,大于等于的部分设置成 111 小的部分设置成 −1-1−1然后求和,看结果是否大于等于 000 来判断是否可行。这道题直接按照权值排序,以原序列标号为下标建立主席树,叶节点权值为在当前树中它应该为的权值,对于询问,中间的询问和,两边的询问最大前后缀即可。代码:#include<bits/stdc++.h>#...

    2024-02-29 10:26:33
  • 中国计算机科学发展,中国计算机的发展趋势

    摘 要:中国计算机硬件是新技术革命的一支主力,也是推动社会向现代化迈进的活跃因素。计算机科学与技术是第二次世界大战以来发展最快、影响最为深远的新兴学科之一。中国计算机硬件产业已在世界范围内发展成为一种...

    2024-02-29 10:26:26
  • 基于SpringBoot+Vue实现前后端分离的旅游网站系统

    基于SpringBoot+Vue实现前后端分离的旅游网站系统

    📚推荐理由: 旅游网站的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品,体验高科技时代带给人们的方便,同时也能让用户体会到与以往常规产品不同的体验风格。...

    2024-02-29 10:26:19
  • RocketMQ系列二 : RocketMQ环境搭建(安装部署)

    RocketMQ系列二 : RocketMQ环境搭建(安装部署)

    在启动NameServer之前,建议修改一下启动时的jvm参数,因为默认的参数都比较大,为了避免内存不够,建议修改小,当然,如果你的内存足够大,可以跳过此处。将jar包上传到服务器,放到/usr/ro...

    2024-02-29 10:25:48
  • HDQ和RDOQ的比较

    HDQ和RDOQ的比较

    HDQ和RDOQ比较

    2024-02-29 10:25:42
  • H5改变主题色

    设置主题色&lt;.

    2024-02-29 10:25:36