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加端口的连接

启动服务端

在这里插入图片描述

客户端连接

在这里插入图片描述

在这里插入图片描述

客户端发送消息

在这里插入图片描述

服务端收到消息

在这里插入图片描述

服务端回复消息

在这里插入图片描述

客户端收到消息

在这里插入图片描述

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Fragment 点击返回键 做返回操作

    Fragment 点击返回键 做返回操作

  • Linux命令之—–watch命令

    Linux命令之—–watch命令

  • potplayer提高帧数_potplayer 60帧

    potplayer提高帧数_potplayer 60帧PotPlayerLAVMadVRSVP4播放器设置这里,推荐使用历史版本的potplayer64,因为新版本的功能有点多余,https://www.videohelp.com/download/PotPlayerSetup64-1.7.16291.exe这个版本是最后一个UI没有大改的,没有直播等无用功能(本地播放器)。安装主程序说明:OpenCodec…

  • 程序员需要什么条件_大厂程序员啥意思

    程序员需要什么条件_大厂程序员啥意思从参加工作到现在,短短的几年内,我投资在自己身上的钱已超过三十多万,光买书籍的钱就已超过总投资的三分之一,买了不少于上千本书,有实体书,也有电子书。这些书不仅提升了我的技术能力,更提升了我的视野和认知。

  • SQL索引优缺点

    SQL索引优缺点前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引。索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。索引的缺点:优点显而易见,同样缺点也是显而易见:1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的

  • java截取某个字符后面的字符串_java如何截取字符串

    java截取某个字符后面的字符串_java如何截取字符串提示:java截取某个字符之前或者之后的字符串文章目录一、java截取某个字符之前或者之后的字符串:1.截取”_”之前字符串2.截取”_”之后字符串二、截取正数第二个”_”后面的内容一、java截取某个字符之前或者之后的字符串:1.截取”_”之前字符串代码如下(示例)://java截取某个字符之前的字符串publicstaticvoidsubstringTest01(){Stringstr=”test_https://www.baidu.com/”;//截

发表回复

您的电子邮箱地址不会被公开。

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