Java小项目——聊天室(单线程版本)

目录

1. 前言

2. 功能实现

3. 模块划分

4. 功能分析

4.1 Socket编程

4.2 ServerSocket

4.3  Socket 

4.4  InetAddress

5. 使用技术

6. 代码


1. 前言

今天写个小项目——聊天室,这个项目是要实现用户的注册、退出以及用户之间的单聊、群聊等功能。现在先写一个单线程的版本,只实现服务器与客户端之间的信息传递。

2. 功能实现

实现客户端与服务器的信息传递

  1. 客户端发数据给服务器,服务器接收数据并打印
  2. 服务器响应数据给客户端,客户端接收数据并打印

3. 模块划分

将整个项目划分为两个模块:客户端、服务器

4. 功能分析

  • 网络编程,每一个聊天室软件在本地电脑上都是一个进程,两人聊天即为两个进程间通信
    •    ->   两个计算机通信(基于TCP协议)
      • ->   将计算机抽象为Java的一个类 
        •  - >   套接字 
          •   ->   利用java.net.Socket & java.net.ServerSocket
            • ->   两个类之间建立联系
  • 4.1 Socket编程

    • 当套接字在两台计算机上建立连接时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。先有客户端套接字,再想办法连接服务器的套接字。
      • java.net.Socket类提供客户端对象

      • java.net.ServerSocket为服务器提供对象与客户端建立连接,并可以监听客户端

    • 建立TCP连接:
      • 1. 服务器实例化ServerSocket对象,并利用端口号(网络中) / 进程ID唯一的表示当前的进程
      • 2. 服务器调用ServerSocket类的accept()阻塞方法,让服务器一直处于等待连接的状态,直到有客户端连接上指定的端口号再做出响应。
      • 3. 客户端在服务器等待时,创建一个Socket对象,并制定IP地址(确定服务器)和端口号(确定服务器中的进程)。
      • 4. Socket 类的构造函数尝试将客户端连接到指定的服务器和端口号。
      • 5. 服务器端的accept() 方法返回一个新的 Socket对象,该对象连接到客户端。
    • 建立连接后,利用I/O进行通信,客户端和服务器两个模块中各有一个输入流和输出流,客户端的输出流连接到服务器的输入流,而客户端的输入流连接到服务器的输出流(为了便于传输利用转换流将字符流转换为字节流)。
    • TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送。
  • 4.2 ServerSocket

 服务器通过ServerSocket类的构造方法获取一个端口,并且侦听客户端请求。

//创建绑定到特定端口的服务器套接字
public ServerSocket(int port) throws IOException 
  •  ServerSocket类的常用方法
//返回此套接字在其上侦听的端口
public int getLocalPort() 
//侦听并接受到此套接字的连接
public Socket accept() throws IOException 
  • 4.3  Socket 

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。

//创建一个 流套接字并将其连接到指定主机上的指定端口号
public Socket(String host, int port) throws UnknownHostException, IOException
  •  Socket 类的常用方法
//返回此套接字连接到的远程端口号
public int getPort()
//返回套接字连接的地址
public InetAddress getInetAddress() 
//返回此套接字的输入流
public InputStream getInputStream() throws IOException 

//返回此套接字的输出流
public OutputStream getOutputStream() throws IOException 
//关闭此套接字 
public void close() throws IOException 
  • 4.4  InetAddress

该类表示互联网协议(IP)地址

//在给定主机名的情况下确定主机的 IP 地址
static InetAddress getByName(String host) 

//返回本地主机
static InetAddress getLocalHost() 

5. 使用技术

  1. Socket编程
  2. I/O

6. 代码

package com.qqy.chat.server.single;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * 服务器
 * Author:qqy
 */
public class SingleServer {
    public static void main(String[] args) {
        try {
            //1.创建服务端的ServerSocket,绑定端口
            ServerSocket serverSocket=new ServerSocket(65521);
            System.out.println("端口号为"+serverSocket.getLocalPort()+"的服务器已启动,等待客户端的连接...");

            //2.接收客户端连接,Socket
            Socket clientSocket=serverSocket.accept();
            System.out.println("接收到客户端"+clientSocket.getRemoteSocketAddress()+"的连接");

            //3.通过Socket发送和接收数据
            //接收的是客户端的OutputStream
            InputStream in=clientSocket.getInputStream();
            //按行读
            Scanner scanner=new Scanner(in);
            System.out.println("接收到客户端的消息:"+scanner.nextLine());
            //发送
            OutputStream out=clientSocket.getOutputStream();
            //字符流 -> 字节流
            OutputStreamWriter writer=new OutputStreamWriter(out);
            //切记加上\n,否则客户端无法读取,阻塞
            writer.write("你好,我是服务器\n");
            //一定要刷新
            // 数据写完后,网络传输会将报文分包,到达目的地后再进行组装。
            writer.flush();

            //4.关闭ServerSocket/Socket
            serverSocket.close();
            System.out.println("服务器已关闭...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package com.qqy.chat.client.single;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * 客户端
 * Author:qqy
 */
public class SingleClient {
    public static void main(String[] args) {
        try {
            //1.创建Socket,指定服务器的地址和服务端口,连接指定服务
            Socket clientSocket=new Socket("127.0.0.1",65521);
            System.out.println("端口号为"+clientSocket.getLocalPort()+"的客户端已创建");
            System.out.println("该客户端已连接上端口号为"+clientSocket.getPort()+"的服务器");

            //2.通过Socket发送和接收数据
            //发送
            OutputStream out=clientSocket.getOutputStream();
            OutputStreamWriter write=new OutputStreamWriter(out);
            write.write("你好,我是客户端\n");
            write.flush();
            //接收的是服务器的OutputStream
            InputStream in =clientSocket.getInputStream();
            Scanner scanner=new Scanner(in);
            System.out.println("接收到服务器的消息:"+scanner.nextLine());

            //3.关闭Socket
            clientSocket.close();
            System.out.println("客户端已关闭...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值