前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVASocket实现聊天室「建议收藏」

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

作者头像
全栈程序员站长
发布2022-07-02 16:15:00
2660
发布2022-07-02 16:15:00
举报

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

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
代码语言:javascript
复制
public Socket accept() throws IOException

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

代码语言:javascript
复制
Socket client = serverSocket.accept();
//对客户端的输入输出流
OutputStream outputStream= client.getOutputStream();
InputStream  inputStream = client.getInputStream();

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

bind

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

代码语言:javascript
复制
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对象我们可以实现对客户端及服务端的读写操作

构造方法
代码语言:javascript
复制
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方法等待客户端请求,另外新起两个线程分别针对客户端的读写进行处理

代码语言:javascript
复制
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和端口,并且启动两个线程分别处理来自服务端的读写

代码语言:javascript
复制
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对象的输入流进行单独处理

代码语言:javascript
复制
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对象的输出流进行单独处理,

代码语言:javascript
复制
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.cn/148336.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JAVASocket实现聊天室
    • 文章目录
    • Sokcet是什么
    • JAVA SOCKET编程中的两个重要对象
      • ServerSocket
        • 构造方法
        • accept
        • bind
        • close
      • Socket
        • 构造方法
        • getInputStream,getOutputStream
        • close
        • 服务端实现
        • 客户端实现
        • 读线程实现
        • 写线程实现
        • 运行结果
    • 聊天室实现
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档