java使用Sokcet和ServerSocket类实现tcp通信

TCP通信:
面向连接,可靠通信

创建客户端程序,使用Socket类

Socket:

public Socket(String host, int port)
 

Creates a stream socket and connects it to the specified port number on the named host.

根据指定的服务器ip,端口号请求与服务端建立连接,连接通过,就可以获得客户端socket

 public OutputStream getOutputStream()

获取字节输出流对象

public InputStream getInputStream()

获取字节输入流对象 

public class client {
    public static void main(String[] args) throws Exception{
        //创建一个Socket对象,并同时请求与服务端程序连接
        //Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
        Socket cli=new Socket("127.0.0.1",8888);
        
        //通过Socket对象获取字节输出流
        OutputStream out = cli.getOutputStream();
        
        //包装原始输出流
        DataOutputStream Dout = new DataOutputStream(out);
        
        Dout.writeUTF("你好");
        
        //关闭
        Dout.close();
        cli.close();
    }
}

 创建服务端,使用ServerSocket类

ServerSocket:
public ServerSocket(int port)

Creates a server socket, bound to the specified port. 

为服务器程序注册端口

public Socket accept()

Listens for a connection to be made to this socket and accepts it.

阻塞等待客户端的连接请求,一旦与某个客户端连接成功,则返回服务端的Socket对象,用于与客户端进行通信 

获取客户端的IP地址,可以调用Socket类中的public SocketAddress getRemoteSocketAddress()方法

public class server {
    public static void main(String[] args) throws Exception{
        //创建一个ServerSocket对象
        ServerSocket ser=new ServerSocket(8888);

        //accept阻塞,等待连接
        Socket cli = ser.accept();
        //获取字节输入流
        InputStream in = cli.getInputStream();
        //包装原始的输入流
        DataInputStream Din = new DataInputStream(in);

        String s = Din.readUTF();
        System.out.println(s);

        //获取客户端的IP地址
        System.out.println(cli.getRemoteSocketAddress());

        //关闭
        Din.close();
        ser.close();
    }
}public class server {
    public static void main(String[] args) throws Exception{
        //创建一个ServerSocket对象
        ServerSocket ser=new ServerSocket(8888);

        //accept阻塞,等待连接
        Socket cli = ser.accept();
        //获取字节输入流
        InputStream in = cli.getInputStream();
        //包装原始的输入流
        DataInputStream Din = new DataInputStream(in);

        String s = Din.readUTF();
        System.out.println(s);

        //获取客户端的IP地址
        System.out.println(cli.getRemoteSocketAddress());

        //关闭
        Din.close();
        ser.close();
    }
}

 实现多发多收:
 

客户端:
public class client {
    public static void main(String[] args) throws Exception{
        //创建一个Socket对象,并同时请求与服务端程序连接
        //Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
        Socket cli=new Socket("127.0.0.1",8888);

        //通过Socket对象获取字节输出流
        OutputStream out = cli.getOutputStream();

        //包装原始输出流
        DataOutputStream Dout = new DataOutputStream(out);

        Scanner sa=new Scanner(System.in);
        while(true)
        {
            String s=sa.nextLine();
            if(Objects.equals(s,"exit"))
            {
                //关闭
                Dout.close();
                cli.close();
                break;
            }
            Dout.writeUTF(s);
            Dout.flush();
        }


    }
}
服务端:
public class server {
    public static void main(String[] args) throws Exception {
        //创建一个ServerSocket对象
        ServerSocket ser = new ServerSocket(8888);

        //accept阻塞,等待连接
        Socket cli = ser.accept();
        //获取字节输入流
        InputStream in = cli.getInputStream();
        //包装原始的输入流
        DataInputStream Din = new DataInputStream(in);

        while (true) {
            try {
                String s = Din.readUTF();

                System.out.println(s);
                //获取客户端的IP地址
                System.out.println(cli.getRemoteSocketAddress());
            } catch (IOException e) {//一旦客户端关闭,就会抛异常
                System.out.println(cli.getRemoteSocketAddress()+"关闭");
                Din.close();
                ser.close();
                break;
            }
        }

        //关闭

    }
}

实现多线程服务器:

任务类:

public class task implements Runnable {
    private Socket socket;
    public task(Socket socket)
    {
       this.socket=socket;
    }
    @Override
    public void run() {
        //通过socket获取字节输入流

        DataInputStream Din = null;
        try {
            InputStream in = socket.getInputStream();
            Din = new DataInputStream(in);

            while (true) {
                String s = null;
                try {
                    s = Din.readUTF();
                } catch (IOException e) {//如果客户端关闭会发送异常
                    System.out.println(socket.getRemoteSocketAddress()+"关闭");
                    socket.close();
                    Din.close();
                    break;
                }
                System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);
            }
        }catch (IOException e) {
            throw new RuntimeException(e);
        }

        }

    }

服务器:
 

public class pthreadServer {
    public static void main(String[] args) throws Exception{
    //创建一个ServerSocket对象
        ServerSocket ser=new ServerSocket(8888);

        while(true)
        {
            Socket socket = ser.accept();//获取Socket对象
            new Thread(new task(socket)).start();
            System.out.println(socket.getRemoteSocketAddress()+"连接成功");
        }
    }
}

结果:

实现群聊功能,一个客户端发消息,其他客户端也可以收到消息

方法:服务器程序用一个集合收集在线的所有客户端socket

服务器:

public class pthreadServer {
    //创建一个集合
    public static List<Socket>list=new ArrayList<>();
    public static Object lock=new Object();
    public static void main(String[] args) throws Exception{
    //创建一个ServerSocket对象
        ServerSocket ser=new ServerSocket(8888);

        while(true)
        {
            Socket socket = ser.accept();//获取Socket对象
            new Thread(new task(socket)).start();
            synchronized (lock) {
                pthreadServer.list.add(socket);
            }


            System.out.println(socket.getRemoteSocketAddress()+"连接成功");
        }
    }
}
public class task implements Runnable {
    private Socket socket;
    public task(Socket socket)
    {
       this.socket=socket;
    }
    @Override
    public void run() {
        //通过socket获取字节输入流

        DataInputStream Din = null;
        try {
            InputStream in = socket.getInputStream();
            Din = new DataInputStream(in);

            while (true) {
                String s = null;
                try {
                    s = Din.readUTF();
                    //把该消息发送给所有客户端的socket
                    sendMsg(s);

                    System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);

                } catch (IOException e) {//如果客户端关闭会发送异常
                    System.out.println(socket.getRemoteSocketAddress()+"关闭");
                    //把该socket客户端移除集合
                    synchronized (pthreadServer.lock) {
                        pthreadServer.list.remove(socket);
                    }
                    socket.close();
                    Din.close();
                    break;
                }

            }
        }catch (IOException e) {
            throw new RuntimeException(e);
        }

        }

    private void sendMsg(String s) throws IOException {
        System.out.println("fa");
        synchronized (pthreadServer.lock) {
            for(Socket socket1:pthreadServer.list)
            {
                //获取一个字节输出流
                OutputStream out = socket1.getOutputStream();
                DataOutputStream dout = new DataOutputStream(out);

                dout.writeUTF(s);//写数据
                dout.flush();


            }
        }


    }

}

 客户端

public class client {
    public static void main(String[] args) throws Exception{
        //创建一个Socket对象,并同时请求与服务端程序连接
        //Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
        Socket cli=new Socket("127.0.0.1",8888);
        new Thread(new clientTask(cli)).start();

        //通过Socket对象获取字节输出流
        OutputStream out = cli.getOutputStream();

        //包装原始输出流
        DataOutputStream Dout = new DataOutputStream(out);

        Scanner sa=new Scanner(System.in);
        while(true)
        {
            String s=sa.nextLine();
            if(Objects.equals(s,"exit"))
            {
                //关闭
                Dout.close();
                cli.close();
                break;
            }
            Dout.writeUTF(s);
            Dout.flush();
        }


    }
}
public class clientTask implements Runnable{
    private Socket socket;
    public clientTask(Socket socket)
    {
        this.socket=socket;
    }
    @Override
    public void run() {
        //通过socket获取字节输入流
        DataInputStream Din = null;
        try {
            InputStream in = socket.getInputStream();
            Din = new DataInputStream(in);
            while (true) {
                String s = null;
                try {
                    s = Din.readUTF();
                    System.out.println(s);
                } catch (IOException e) {//自己关闭连接或者服务器关闭连接,就会异常
                    System.out.println("自己关闭或者服务器关闭");
                    socket.close();
                    Din.close();
                    break;
                }
                System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);
            }
        }catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试——Postman Script脚本功能

Postman作为软件测试里一款非常流行的调试工具&#xff0c;给我们提供了一个执行JavaScript脚本的环境&#xff0c;所以我们可以使用js语言编写脚本来解决一些接口自动化的问题&#xff0c;比如接口依赖、接口断言等等。Postman有Pre-RequestScript和Tests两个编写js脚本的模块…

赛氪网参与第61届中国高等教育博览会,助力产教融合与科教融汇

为深入贯彻党的二十大精神&#xff0c;落实立德树人根本任务&#xff0c;推动高等教育装备现代化&#xff0c;第61届中国高等教育博览会&#xff08;以下简称“高博会”&#xff09;于近日在福建省福州市隆重开幕。作为高等教育领域内的综合性品牌博览会&#xff0c;此次高博会…

将MySQL数据库查询结果导出为txt文档,并建成实体类

目录 第一章、功能需求和分析1.1&#xff09;具体需求1.2&#xff09;分析需求转为小的问题1、如何获得数据库表的字段&#xff1f;2、如何将数据库查询结果导出&#xff1f;3.将获得的数据库查询结果转为驼峰式4.让AI建个实体类 友情提醒: 先看文章目录&#xff0c;大致了解文…

C语言之文件操作【万字详解】

目录 一.什么是文件&#xff1f; 二.为什么要使用文件&#xff1f; 三.文件的分类 3.1.程序文件 3.2.数据文件 四.二进制文件和文本文件 五.文件的打开和关闭 &#xff08;重点&#xff09; 5.1流和标准流 5.1.1何为流&#xff1f; 5.1.2.标准流 5.2文件指针 5.3文件的打开和关…

[Android]Jetpack Compose加载图标和图片

一、加载本地矢量图标 在 Android 开发中使用本地矢量图标是一种常见的做法&#xff0c;因为矢量图标&#xff08;通常保存为 SVG 或 Android 的 XML vector format&#xff09;具有可缩放性和较小的文件大小。 在 Jetpack Compose 中加载本地矢量图标可以使用内置的支持&…

ubuntu如何运行python程序

打开LINUX UBUNTU操作系统。 找到左边的TERMINAL&#xff0c;打开窗口。 输入python&#xff0c;如果没有安装&#xff0c;就会提示需要安装。 如果已经安装好python3&#xff0c;直接输入&#xff0c;那么就会进入。 exit()就可以退出python3的模式。 创建一个文件&#xff0c…

java多线程-悲观锁、乐观锁

简介 悲观锁&#xff1a;没有安全感&#xff0c;一上来就直接加锁&#xff0c;每次只能一个线程进入访问&#xff0c;访问完毕之后&#xff0c;再解锁。线程安全&#xff0c;但是性能差。乐观锁&#xff1a;很乐观&#xff0c;一开始不上锁&#xff0c;认为没有问题。等到要出现…

揭秘“磁盘管理未知没有初始化”背后的秘密与应对策略

在日常使用电脑的过程中&#xff0c;我们有时会遇到一个令人头疼的问题——磁盘管理显示“未知没有初始化”。这种情况意味着系统无法正确识别和管理该磁盘&#xff0c;导致我们无法访问其中的数据。那么&#xff0c;究竟什么是“磁盘管理未知没有初始化”&#xff1f;又该如何…

等保测评之主机测评详解(二级)

等保测评之主机测评详解&#xff08;二级&#xff09;服务器——Windows 身份鉴别: 测评项a&#xff09;&#xff1a; a&#xff09;应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换&#xff1b; 整改方…

案例:SpringBoot集成Sharding-JDBC实现分表分库与主从同步(详细版)

案例&#xff1a;SpringBoot集成Sharding-JDBC实现分表分库与主从同步&#xff1a;详细版 1. 案例分析2. 主从同步2.1 主从数据库准备2.2 简单插点数据 3 案例代码3.1 application.properties配置信息3.2 测试 4. 遇到的坑4.1 水平分表时的属性设置4.2 绑定表的配置 1. 案例分析…

C语言为什么没有应用层开发的库

C语言是一门“古老”的语言了&#xff0c;在中大型的应用层项目开发中&#xff0c;C,Java,Python,C# 等其他编程语言能够更好地胜任&#xff0c;为C语言开发应用层的库简直是费力不讨好&#xff0c;所以几乎没人这么做。在开始前我有一些资料&#xff0c;是我根据网友给的问题精…

退役军人档案管理系统|DW-S403是一套成熟系统

退役军人档案管理系统是一种专门用于管理退役军人档案的信息系统&#xff0c;旨在提高退役军人档案的管理效率和利用价值。该系统采用先进的信息技术手段&#xff0c;对退役军人的档案进行全面、精准、高效的管理&#xff0c;为退役军人的就业、社保、优抚安置等提供有力支持。…

FreeRTOS使用中断相关的函数导致程序卡死解决办法

1.现象 想在串口中断中实现任务通知的功能&#xff0c;所以在串口中断服务函数中使用了xTaskGenericNotifyFromISR&#xff08;&#xff09;函数来发送通知&#xff0c;发现一进入中断服务函数&#xff0c;程序就卡死了。下边是串口初始化和中断服务函数: void Usart_Init_U(…

这届年轻人,对AI对象上头

在AI技术飞速发展的今天&#xff0c;虚拟对象这一概念也流行了起来。从AI女友到AI男友&#xff0c;这些基于人工智能的AI社交应用正在改变我们对情感陪伴的认知。本文深入探讨了AI虚拟对象的兴起、用户需求、商业模式以及技术局限&#xff0c;不妨来看一下。 继2023年文生文大语…

标准版/开源版 移动端新增页面使用文档

在标准版开发的实际使用中&#xff0c;随着用户移动端的产品和信息内容不断增多&#xff0c;新增页面来展示对应的产品详情、模块等内容。针对一些概念或者步骤较多的内容&#xff0c;可以新增子页面构建多级模块结构&#xff0c;帮助用户快速定位。 下面就如何新增页面做一讲…

网际互联及OSI七层模型

1什么是OSI七层模型 2OSI每一个Layer的定义 及用途 3如何使用OSI参考模型分析网络通信过程 一、网际互联 &#xff08;一&#xff09;OSI的概念&#xff1a; open system interconnect开放系统互联参考模型&#xff0c;是有ISO&#xff08;国际标准化组织&#xff09;定义…

混合现实(MR)技术的应用场景

混合现实&#xff08;MR&#xff09;技术将虚拟世界和现实世界融合在一起&#xff0c;用户可以在现实世界中看到和与虚拟物体进行交互&#xff0c;同时还可以感知周围的真实环境。MR技术具有广阔的应用前景&#xff0c;可以应用于各行各业。以下是一些MR的应用场景。北京木奇移…

iOS ------代理 分类 拓展

代理协议 一&#xff0c;概念&#xff1a; 代理&#xff0c;又称委托代理&#xff08;delegate&#xff09;&#xff0c;是iOS中常用的一种设计模式。顾名思义&#xff0c;它是把某个对象要做的事委托给别的对象去做。那么别的对象就是这个对象的代理&#xff0c;代替它来打理…

Linux部署MySQL8.0—手把手保姆级教程

&#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru &#x1f525; 系列专栏&#xff1a;《Docker容器化部署系列》 《Java每日面筋》 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 目录 一、下载MySQL8.0安装包二、安装MySQ…

springboot的坑

问题&#xff1a;使用Autowired注入一个service&#xff0c;然后写了两个接口&#xff0c;第一个接口与请求时显示注入的service为空一直报错&#xff0c;但是第二个接口请求时service竟然不是空&#xff1f;在这里插入图片描述 凶手找到了&#xff0c;是private修饰。果然没仔…