JAVASocket实现聊天室「建议收藏」

JAVASocket实现聊天室「建议收藏」JAVASocket实现聊天室文章目录JAVASocket实现聊天室Sokcet是什么JAVASOCKET编程中的两个重要对象ServerSocket构造方法acceptbindcloseSocket构造方法getInputStream,getOutputStreamclose聊天室实现服务端实现客户端实现读线程实现写线程实现运行结果Sokcet是什么socket本质上是两个端点之间的通…

大家好,又见面了,我是你们的朋友全栈君。

JAVASocket实现聊天室

在这里插入图片描述

Sokcet是什么

socket本质上是两个端点之间的通信桥梁,两个端点相互连接,并且打开远程之间的网络IO,从而可以像对本地文件读写一样,JAVA对socket编程有着友好的支持,并且针对客户端和服务端抽象了不同的服务对象

JAVA SOCKET编程中的两个重要对象

JDK对Socket编程抽象了两个类ServerSocketSocket,分别封装了客户端和服务端的基本通信API

ServerSocket

JDK提供的服务端实现,主要用于监听服务端口,并且接受来自该端口的客户端请求,并且生成来自客户端的Socket对象。

几个重要的方法:

构造方法

  • ServerSocket()
  • ServerSocket(int port)
  • ServerSocket(int port,int backlog)
  • ServerSocket(int port,int backlog,InnetAddress bindAddr)

上述构造方法设计到大致三个参数,port(端口),backlog请求客户端队列最大长度,bindAddr,将要绑定的IP实现,如果不指定默认本地IP。

accept

public Socket accept() throws IOException

accept方法主要是在开启端口监听之后接受一个客户端的连接请求,如果没有请求进来,那么accept方法会一直阻塞,直到一个客户端的请求进入,accept方法在接受一个客户端的请求之后,会生成一个客户端的Socket对象,这个对象封装了客户端的IO请求。

Socket client = serverSocket.accept();
//对客户端的输入输出流
OutputStream outputStream= client.getOutputStream();
InputStream  inputStream = client.getInputStream();

服务端可通过这个Socket对象获取对客户端的输入流和输出流,这样服务端就可以读取到客户端发送来的的消息,并且可以向客户端发送消息

bind

bind方法是真正实现socket套接字绑定IP和端口的实现,默认在ServerSocket的构造方法中会进行调用。

public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { 
   
        ...
        try { 
   
            bind(new InetSocketAddress(bindAddr, port), backlog);
        } catch(SecurityException e) { 
   
            close();
            throw e;
        } catch(IOException e) { 
   
            close();
            throw e;
        }
}
       

close

当主动调用close方法后,服务器会释放当前绑定的端口,并且自动断开和所有客户端之间的连接,只有主动执行了ServerSocket的close()方法,isClosed()方法才返回true;否则,即使ServerSocket还没有和特定端口绑定,isClosed()方法也会返回false,这是因为服务端内部维护了一个closed变量,初始化为false,只有在调用了close方法才会将closed变量置为true

Socket

JDK提供的Socket套接字实现类,主要封装了端的IO操作,通过Socket对象我们可以实现对客户端及服务端的读写操作

构造方法

Socket(InetAddressaddress, int port);
Socket(InetAddress address,int port, boolean stream);
Socket(String host, intprot);
Socket(String host, intprot, boolean stream);
Socket(SocketImpl impl)
Socket(String host, intport, InetAddress localAddr, Socket(InetAddress address,int port, InetAddress localAddr, int localPort)
ServerSocket(int port);
ServerSocket(int port, intbacklog);
ServerSocket(int port, intbacklog, InetAddress bindAddr)

其中address、host和port分别是双向连接中另一方的IP地址、 主机名和端口号,stream指明socket是流socket还是数据报 socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地 址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。

Socket(String host, intprot)

常用的构造方法默认指定host和port,表示要建立的远程连接的服务端IP和端口,在服务端开启端口监听之后,客户端可以得到一个连接到服务端的Socket对象,同时服务端也会得到一个连接到客户端的Socket对象,这样双方可基于Socket实现双向通信,发送并且接受消息

getInputStream,getOutputStream

获取对应端的输入输出流,当双方建立连接后,双方互相持有封装了对方IO操作的Sokcet对象,通过Socket对象获取对应的输入输出流实现双向通信。

close

当客户端的Socket关闭连接时,服务端与客户端的连接自动关闭,但是服务端会继续监听端口,等待新的连接进来。

当服务端的Sokcet关闭连接时,服务端与所有客户端的连接将全部断开,并且释放对应监听接口

聊天室实现

服务端实现

监听端口,调用accept方法等待客户端请求,另外新起两个线程分别针对客户端的读写进行处理

public class Server { 
   

    public static final Integer port =80;

    public static void main(String[] args) throws IOException { 
   
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("服务端监听 "+port+" 端口成功!,等待客户端连接");
        while (true){ 
   
            Socket client = serverSocket.accept();
            System.out.println("一个新的客户端进来了");
            new WriteHelper(client.getOutputStream(),"连接客户端成功!,可以畅所欲言了").start();
            new PrintHelper(client.getInputStream(),"服务端").start();
        }
    }


}

客户端实现

绑定ip和端口,并且启动两个线程分别处理来自服务端的读写

public class Client { 
   

    public static void main(String[] args) throws IOException, InterruptedException { 
   
        Socket socket = new Socket("127.0.0.1", 80);
        new WriteHelper(socket.getOutputStream(),"连接服务端成功!,可以畅所欲言了").start();
        new PrintHelper(socket.getInputStream(),"客户端").start();
    }
}

针对Socket的输入输出流实现单独线程处理,读写不互相收影响

读线程实现

主要针对Sokcet对象的输入流进行单独处理

public class PrintHelper extends Thread{ 
   

    private InputStream inputStream;
    private String type;

    public PrintHelper(InputStream inputStream,String type) { 
   
        this.inputStream=inputStream;
        this.type=type;
    }

    public void run() { 
   
        byte[] bytes = new byte[1024];
        int length;
        try { 
   
            while (true){ 
   
                if (((length=inputStream.read(bytes))>1)){ 
   
                    String s = new String(bytes, 0, length);
                    LocalDateTime nowLocalDate = LocalDateTime.now();
                    String time = nowLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    System.out.println(" "+time+" "+type+" : "+s);
                    System.out.println("____________________________________________");
                }
            }
        } catch (IOException e) { 
   
            e.printStackTrace();
        }
    }

}

写线程实现

主要针对Socket对象的输出流进行单独处理,

public class WriteHelper extends Thread{ 
   

        private OutputStream outputStream;

        public WriteHelper(OutputStream outputStream,String message) { 
   
            System.out.println(message);
            System.out.println("============================");
            this.outputStream=outputStream;
        }

        public void run() { 
   
            Scanner scanner = new Scanner(System.in);
            while(true){ 
   
                String next = scanner.next();
                try { 
   
                    outputStream.write(next.getBytes());
                    outputStream.flush();
                } catch (IOException e) { 
   
                    e.printStackTrace();
                }
            }
        }
}

运行结果

需要先启动服务端,开启端口监听,再启动客户端,实现IP加端口的连接

启动服务端

在这里插入图片描述

客户端连接

在这里插入图片描述

在这里插入图片描述

客户端发送消息

在这里插入图片描述

服务端收到消息

在这里插入图片描述

服务端回复消息

在这里插入图片描述

客户端收到消息

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148336.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 虚拟IP简介「建议收藏」

    虚拟IP简介「建议收藏」什么是虚拟IP虚拟IP(VirtualIPAddress,简称VIP)是一个未分配给真实弹性云服务器网卡的IP地址。弹性云服务器除了拥有私有IP地址外,还可以拥有虚拟IP地址,用户可以通过其中任意一个IP(私有IP/虚拟IP)访问此弹性云服务器。同时,虚拟IP地址拥有私有IP地址同样的网络接入能力,包括VPC内二三层通信、VPC之间对等连接访问,以及弹性公网IP、VPN、云专线等网络接入。多个主备部署的弹性云服务器可以在绑定虚拟IP地址时选择同一个虚拟IP地址。用户可以为该虚拟IP地址绑定一个弹

    2022年10月20日
    0
  • navcat15 for mysql激活码 3月最新注册码

    navcat15 for mysql激活码 3月最新注册码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    40
  • 开源库TinyXML2简介及使用

    开源库TinyXML2简介及使用TinyXML2是一个开源、简单、小巧、高效的C++XML解析器,它只有一个.h文件和一个.cpp文件组成,可以轻松集成到其它程序中。它解析XML文档并从中构建可以读取、修改和保存的文档对象模型(DocumentObjectModel,DOM)。它不能解析DTD(DocumentTypeDefinitions,文档类型定义)或XSL(eXtensibleStylesheetLan…

    2022年6月14日
    163
  • 内部服务器500错误原因解决方法_什么是内部服务器错误

    内部服务器500错误原因解决方法_什么是内部服务器错误http500内部服务器错误的解决方法这个错误整整浪费了我下午的时间,在网上有很多的方法,当然我也是从那些繁多的方法中一点点的搞定IIS的,首先你要先装好IIS,XPSP2中的应该是5.1版本的,安装方法:1->打开控制面板,选择添加删除程序2->选择添加删除组件,选择Internet信息服务,也就是IIS3->点击下一步安装就好了安装好之后也许你的机子会正常的显示http://localho

    2022年8月11日
    8
  • mac phpstorm 激活码【2021.8最新】

    (mac phpstorm 激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSW…

    2022年3月26日
    69
  • 3D场景的制作步骤

    3D场景的制作步骤分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!               2.4&nbs

    2022年6月9日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号