JAVA Socket编程——基于ServerSocket建立聊天服务器

该篇博客写一下关于Socket编程,java实现基于ServerSocket的聊天服务器。可实现客户端与客户端之间的群聊(win下cmd命令行模拟客户端)

该篇博客目录

1、Socket介绍
2、Socket编程在客户端与服务端的使用注意
3、java实现基于ServerSocket的聊天服务器

一、Socket介绍

Socket类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。

1、Socket特点

  • Socket基于TCP链接,数据传输有保障
  • Socket适用于建立长时间链接
  • Socket编程通常应用于即时通讯

2、Socket链接的建立过程

  • 服务器监听
  • 客户端发出请求
  • 建立链接
  • 通信

二、Socket编程在客户端与服务端的使用注意

  • 对于客户端,需要使用new Socket(ip,port)
  • 对于服务器端,需要借助于ServerSocket 的accept方法获得与特定的客户端相关联的Socket实例
  • 通信的双方借助于socket里面的方法,获得输出流和输入流完成相关的通信的逻辑处理

三、java实现基于ServerSocket的聊天服务器

下面是每个类具体作用

  • MyServerSocket:测试类
  • GetSocket:服务器端的侦听类,负责获取连接成功的客户端
  • ChatSocket:客户端的通信,向客户端发送和输出信息,实现单独线程的通信
  • ChatManager:聊天管理,实现Socket入队列,发送数据

MyServerSocket类

package Socket_1;

/*
 *
 * 测试类
 * 
 */

public class MySeverSocket {

    public static void main(String[] args) {
        new GetSocket().start();
    }

}

GetSocket类(线程)
关于accept:若未被接收请求,accept会一直处于等待状态,线程阻塞(所以accept等这类阻塞方法,不能在主线程中使用,否主线程会被阻塞,需要放置到独立的线程当中)

package Socket_1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

/*
 *服务器端的侦听类,负责获取连接成功的客户端
 *获取socket与客户端通信 
 *
 */
public class GetSocket extends Thread {
    @Override
    public void run() {

        try {
            //创建绑定到特定端口的服务器套接字  1-65535
            ServerSocket serversocket = new ServerSocket(62224);
            while(true) {
                //建立连接,获取socket对象
                Socket socket=serversocket.accept();
                //消息提示框
                JOptionPane.showMessageDialog(null, "有客户端连接到了本机62224端口哦");
                //与客户端通信
                ChatSocket cs=new ChatSocket(socket);
                cs.start();
                //添加socket到队列
                ChatManager.GetChatManager().AddChatPeople(cs);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

ChatSocket类(线程)
这里有个关于getInputStream/getOutputStream在客户端还是服务端的作用区别

客户端上的使用

1.getInputStream方法可以得到一个输入流,客户端的Socket对象上的getInputStream方法得到输入流其实就是从服务器端发回的数据。

2.getOutputStream方法得到的是一个输出流,客户端的Socket对象上的getOutputStream方法得到的输出流其实就是发送给服务器端的数据。

服务器端上的使用

1.getInputStream方法得到的是一个输入流,服务端的Socket对象上的getInputStream方法得到的输入流其实就是从客户端发送给服务器端的数据流。

2.getOutputStream方法得到的是一个输出流,服务端的Socket对象上的getOutputStream方法得到的输出流其实就是发送给客户端的数据。

package Socket_1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;


/*
 *与客户端通信,向客户端发送信息 
 *实现单独线程的通信处理
 */
public class ChatSocket extends Thread {

    Socket socket;
    public ChatSocket(Socket socket) {
        this.socket=socket;
    }

    /*
     *向客户端输出信息 
     */
    public void Out(String str) {
        try {
            socket.getOutputStream().write(str.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /*
     *
     * 向客户端发送消息
     */
    @Override
    public void run() {
        Out("success\n");
        try {
             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));

            String line=null;
            while((line=br.readLine())!=null)
            {
                System.out.println(line);
                ChatManager.GetChatManager().Send(this, line);
            }
            br.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

ChatManager类

package Socket_1;

import java.util.Vector;

/*
 * 
 * 添加socket到队列,发送数据
 * 
 */

public class ChatManager {
    //因为一个聊天系统只有一个聊天管理,所以需进行单例化private
    /*
     *单例化 
     */
    private ChatManager() {}
    private static final ChatManager cm=new ChatManager();
    public static ChatManager GetChatManager() {
        return cm;
    }

    //创建保存socket的队列
    Vector vector=new Vector();

    //添加聊天人
    public void AddChatPeople(ChatSocket cs) {
        vector.add(cs);
    }

    //群发消息
    public void Send(ChatSocket cs,String str) {
        for (int i = 0; i < vector.size(); i++) {
            ChatSocket chatsocket=(ChatSocket)vector.get(i);
            if(!cs.equals(chatsocket))
            {
                chatsocket.Out(str);
            }
        }
    }

}
win下打开命令行模拟客户端,eclipse模拟服务器

命令行下键入:telnet localhost 端口号

JAVA Socket编程——基于ServerSocket建立聊天服务器_第1张图片

实现群聊

JAVA Socket编程——基于ServerSocket建立聊天服务器_第2张图片

整个服务端流程

  • serversocket侦听
  • socket添加到队列
  • 通过输入输出流实现向客户端的发送/接受信息

你可能感兴趣的:(●,Java基础)