Java简易版聊天室(单线程)

一、项目描述

支持单客户端和服务器端的通信。

二、项目功能

客户端和服务器端相互发送信息、接收信息。

三、项目开发环境

IntelliJ IDEA

四、项目技术

Java基础、网络编程、JavaIO、Maven管理。

五、项目分析

套接字:TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。套接字用(IP地址:端口号)表示。

5.1 服务端和客户端的连接

根据Socket类(客户端)和ServerSocket类(服务器端)的构造函数,客户端和服务器端要想通信,则由这两个类构成对象的端口地址(即IP地址)应相同。这样客户端和服务器端就建立了联系,服务器端首先启动,然后调用accept()等待客户端连接,accept()函数会一直阻塞直到连接到客户端为止。当客户端的IP地址和服务器端相同时,客户端启动即与服务器端进行连接。

IP地址和端口号除人为设定外,还可以通过在运行时设置main函数参数来设定。

5.2客户端和服务端的通信

首先要明确一点,客户端的Socket对象和服务器端接收的Socket对象不是同一个!因为它们分别要进行读数据和写数据,二者之间的读写是互不干扰的。客户端的Socket对象假设是client,服务器端接收的Socket对象假设是server。client读数据,对于客户端来说是输入流,而对于server来说是输出流。同样,client写数据,对于客户端来说是输出流,对于server来说是输入流。

Java简易版聊天室(单线程)_第1张图片

因此,二者的写数据和读数据互不干扰。写数据可以通过OutputStream类和OutputStreamWriter类中的方法写,读数据可以通过InputStream类和Scanner类的方法去读。

5.3客户端的关闭

一般客户端可以根据用户的选择决定是否关闭,关闭的时候不仅包括客户本身,还有客户端的输出流和输入流,而服务器端一般不会关闭。

六、项目流程

1.创建项目(最好选择Maven项目)--chatroom

2.创建两个模块,分别为chat-room-server和chat-room-client。

3.在两个模块中分别创建主类(SingleThreadServer和SingleTnreadClient)

4.服务器端(SingleThreadServer)

  4.1创建ServerSocket对象。

  4.2接收客户端。

  4.3接收客户端信息。

  4.4发送信息。

所用到的函数及其功能如下:

//创建ServerSocket对象
1.public ServerSocket(int port)   创建绑定到指定端口的服务器套接字。
2.public SocketAddress getLocalSocketAddress()  返回此套接字绑定到的端点的地址。
//接收客户端对象
3.public Socket accept() throws IOException  侦听要连接到此套接字并接受它。 该方法将阻塞直到建立连接。
4.public SocketAddress getRemoteSocketAddress()  返回此套接字连接,或端点的地址null如果是未连接。
//接收信息
5.public InputStream getInputStream()throws IOException  返回此套接字的输入流。 
6.Scanner(InputStream source)  构造一个新的 Scanner ,产生从指定输入流扫描的值。 
7.public String nextLine()  将此扫描仪推进到当前行并返回跳过的输入,它可以缓冲搜索行的所有输入。
//发送信息
8.public OutputStream getOutputStream() throws IOException  返回此套接字的输出流。如果此套接字具有相关联的通道,则生成的输出流将其所有操作委派给通道。 如果通道处于非阻塞模式,则输出流的write操作将抛出IllegalBlockingModeException。
9.public OutputStreamWriter(OutputStream out)  创建一个使用默认字符编码的OutputStreamWriter。 
 

5.客户端(SingleTnreadClient)

  5.1准备Socket对象

  5.2接收信息

  5.3发送信息

  5.4关闭客户端(包括Socket对象,输入流和输出流)

所用到的函数和功能如下:

//创建Socket对象
1.public Socket(InetAddress address,int port) throws IOException  创建流套接字并将其连接到指定IP地址的指定端口号。 
//接收信息
2.public InputStream getInputStream()throws IOException  返回此套接字的输入流。 
3.Scanner(InputStream source)  构造一个新的 Scanner ,产生从指定输入流扫描的值。 
4.public String nextLine()  将此扫描仪推进到当前行并返回跳过的输入,它可以缓冲搜索行的所有输入。
//发送信息
5.public OutputStream getOutputStream() throws IOException  返回此套接字的输出流。如果此套接字具有相关联的通道,则生成的输出流将其所有操作委派给通道。 如果通道处于非阻塞模式,则输出流的write操作将抛出IllegalBlockingModeException。
6.public OutputStreamWriter(OutputStream out)  创建一个使用默认字符编码的OutputStreamWriter。 
//关闭
7.public void close() throws IOException  关闭此套接字。 
8.public void close() throws IOException  关闭此输入流并释放与流相关联的任何系统资源。 该close的方法InputStream什么都不做。 
9.public void close() throws IOException  关闭此输出流并释放与此流相关联的任何系统资源。 close的一般合同是关闭输出流。 封闭流不能执行输出操作,无法重新打开。 

6.测试

7.打包

七、代码实现

package SingleThread;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class SingleThreadServer {
    public static void main(String[] args) throws IOException {

        int port=7777;
        //通过设置main函数参数设置端口号
        if(args.length>0){
            port=Integer.parseInt(args[0]);//把字符串类型的数据转为int型。
        }
        //1.创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("服务器启动:" + serverSocket.getLocalSocketAddress());//返回此套接字在其上侦听的端口地址(host)
        //2.等待客户端连接
        System.out.println("等待客户端连接。。。。。。\n");
        Socket clientSocket = serverSocket.accept();//侦听并接收到此套接字的连接
        System.out.println("客户端信息:" + clientSocket.getRemoteSocketAddress());//返回此套接字连接的端口地址
        //3.接收数据,发送数据
            //3.1接收数据
        InputStream clientInput = clientSocket.getInputStream();//返回此套接字的输入流
        Scanner scanner = new Scanner(clientInput);
        String clientData = scanner.nextLine();//读取客户端的信息
        System.out.println("来自客户端的信息:" + clientData);
            //3.2发送数据
        OutputStream clientOutput = clientSocket.getOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(clientOutput);
        writer.write("你好,欢迎连接服务器\n");//用户读取到的数据
        writer.flush();//flush()强制把缓冲区的数据写到输出流中。

        }
}
package SingleThread;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class SingleThreadClient {
    public static void main(String[] args) throws IOException {
     //1.创建客户端,连接到服务器。
        int port=7777;
        if(args.length>0){
            port=Integer.parseInt(args[0]);
        }else{
            System.out.println("端口参数不正确,采用默认参数");
        }
        String host="127.0.0.1";
        if(args.length>1){
            host=args[1];
        }
        Socket clientSocket=new Socket(host,port);
        //2.接收,发送数据
        //2.1发送数据
        OutputStream clientOutput=clientSocket.getOutputStream();
        OutputStreamWriter writer=new OutputStreamWriter(clientOutput);
        writer.write("你好,我是客户端\n");//写到输出流中,服务器端读取到的数据
        writer.flush();
        //2.2接收数据
        InputStream clientInput=clientSocket.getInputStream();
        Scanner scanner=new Scanner(clientInput);
        String serverData=scanner.nextLine();
        System.out.println("来自服务器端的数据:"+serverData);
        //3.客户端的关闭
        clientOutput.close();
        clientInput.close();
        clientSocket.close();
    }
}

先启动服务器端,结果为:

Java简易版聊天室(单线程)_第2张图片

再启动客户端,结果客户端显示为:

Java简易版聊天室(单线程)_第3张图片

服务器端显示为:

Java简易版聊天室(单线程)_第4张图片

 

你可能感兴趣的:(Java)