zoukankan      html  css  js  c++  java
  • 使用ServerSocket建立聊天服务器(一)

    -------------siwuxie095

       

       

       

       

       

       

       

    工程名:TestMyServerSocket

    包名:com.siwuxie095.socket

    类名:MyServerSocket.java(主类)、ServerListener.java、ChatSocket.java

       

       

    工程结构目录如下:

       

       

       

       

       

    MyServerSocket.java(主类):

       

    package com.siwuxie095.socket;

       

    /**

    * 聊天服务器,仅能向客户端发送数据

    *

    * @author siwux

    *

    */

       

    public class MyServerSocket {

     

    /**

    * 这是主类(主线程),启动线程ServerListener进行监听,

    * 当有Socket对象进行连接时,在线程ServerListener

    * 启动线程ChatSocket

    *

    * @param args

    */

       

    public static void main(String[] args) {

     

    //运行线程ServerListener,使用匿名对象

    new ServerListener().start();

    }

       

    }

       

       

       

    ServerListener.java:

       

    package com.siwuxie095.socket;

       

    import java.io.IOException;

    import java.net.ServerSocket;

    import java.net.Socket;

       

    import javax.swing.JOptionPane;

       

    //创建线程 ServerListener,将有阻塞的代码放到这个独立的线程中

    public class ServerListener extends Thread {

       

    // 复写run()

    @Override

    public void run() {

    try {

       

    // 创建一个ServerSocket对象,并指定端口:12345

    // 端口的范围:1~65535,通常都指定较大的数字,

    // 这样和较小的或系统预留的端口分开

    // 有异常抛出,用 try catch 捕获

    ServerSocket serverSocket = new ServerSocket(12345);

       

     

    // ServerSocket创建完成后需要侦听客户端的连接

    // 调用accept()方法,这是一个阻塞的方法,

    // 会阻塞当前的线程,对于有阻塞的代码,应该放到独立的线程中

    //ServerListener 就是一个独立的线程)

    // 返回值是Socket类型,创建以接收返回值

    // accept()被执行且socket被赋值,说明有客户端连接

    //每当有一个客户端连接到ServerSocketaccept()都会返回一个新的Socket对象

    //如果有多个客户端来连接当前的服务器ServerSocket,就会有多个Socket对象出现

    //需要一个while循环来循环监听

    while (true) {

     

    Socket socket = serverSocket.accept();

       

    // 建立连接时

    // 弹出提示框:有客户端连接到本机的 12345 端口

    JOptionPane.showMessageDialog(null, "有客户端连接到本机的 12345 端口");

     

    //由于每一个socket要与一个独立的客户端进行通信

    //所以要将socket传递给新的线程:ChatSocket(用于Socket通信)

    //每一个socket都有一个独立的ChatSocket线程

    //每一个ChatSocket线程之间是相互独立的,它们不能相互沟通数据

    //运行该线程,使用匿名对象

    new ChatSocket(socket).start();

     

    }

     

       

    } catch (IOException e) {

    e.printStackTrace();

    }

       

    }

       

    }

       

       

       

    ChatSocket.java:

       

    package com.siwuxie095.socket;

       

    import java.io.BufferedWriter;

    import java.io.IOException;

    import java.io.OutputStream;

    import java.io.OutputStreamWriter;

    import java.io.UnsupportedEncodingException;

    import java.net.Socket;

       

    /**

    * 代码段(4)一直包装到带缓冲的字符流,输出时需要flush进行强制输出

    * 代码段(3)是简单的字节流进行输出

    *

    * (4)等效于(3)等效于(1)(2)

    *

    * (4)=(3)=(1)+(2)

    *

    * 主要使用(4),其他注释起来

    *

    * @author siwux

    *

    */

       

    //创建用于Socket通信的线程:ChatSocket

    public class ChatSocket extends Thread {

     

    Socket socket;

     

    //创建构造方法,传入Socket对象

    public ChatSocket(Socket socket) {

    this.socket=socket;

    }

     

     

     

    //(1)

    public void output(String out) {

    try {

    //socket.getOutputStream() OutputStream

    //实际上是 OutputStream.write() os.write()

    // getBytes()指定编码

    //有异常抛出,用 try catch 捕获

    socket.getOutputStream().write(out.getBytes("UTF-8"));

    } catch (UnsupportedEncodingException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

     

     

     

    //复写run()方法

    @Override

    public void run() {

     

    // //(2)

    // int count=0;

    // while (true) {

    // output("loop:"+count+"-");

    // count++;

    // try {

    // sleep(1000);

    // } catch (InterruptedException e) {

    // e.printStackTrace();

    // }

    // }

     

     

     

     

    // //(3)

    // try {

    // OutputStream os=socket.getOutputStream();

    // int count=0;

    // while (true) {

    // String outString="loop:"+count+"-";

    // byte outByte[]=outString.getBytes("UTF-8");

    // os.write(outByte);

    // count++;

    // sleep(1000);

    //

    // }

    //

    // } catch (IOException e) {

    // e.printStackTrace();

    // } catch (InterruptedException e) {

    // e.printStackTrace();

    // }

     

     

     

     

    //(4)

    try {

     

    //对当前的Socket执行 数据输出相关功能的包装

    //使用getOutputStream()获取输出流,通过输出流向外输出数据

    //返回值是OutputStream类型,创建以接收返回值

    OutputStream os=socket.getOutputStream();

     

    //创建一个BufferedWriter作为数据的输出,传入匿名对象,指定编码,层层包装

    BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));

     

     

    //通过BufferedWriter可以在Socket中直接输出一行字符串

    int count=0;

    //一直循环

    while (true) {

     

    //BufferedWriter输出字符串

    bw.write("loop:"+count+"-");

    //因为带缓冲,所以需要强制输出,不然无法输出

    bw.flush();

    //1秒执行一次

    //有异常抛出,用 try catch 捕获

    sleep(1000);

    count++;

     

    }

     

    } catch (IOException e) {

    e.printStackTrace();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

     

     

    }

    }

       

       

    运行后,终止按钮(Terminate)长亮,即 当前程序正在运行 且 没有停止

       

       

    而且,此时也没有任何提示框,即当前程序被阻塞在 ServerListener.java 的:

    Socket socket=serverSocket.accept();

       

       

       

    打开 CMD 窗口,输入:telnet 127.0.0.1 12345 telnet localhost 12345

    (即 本机地址+端口),回车。此时,会弹框提示:

       

       

       

       

    点击确定,CMD 窗口开始无限循环输出:

       

       

       

       

    此时程序并未停止,可以继续打开多个 CMD 窗口进行连接,

    相当于新建客户端,也是从一开始进行输出

       

    点击 终止按钮(Terminate),可结束运行

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    让android系统中任意一个view变成进度条
    AIDL(2):服务端回调客户端
    java 简单的des加密示例
    java中的集合:继承关系和简介
    java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore
    java中的线程(3):线程池类 ThreadPoolExecutor「线程池的类型、参数、扩展等」
    java中的线程(2):如何正确停止线程之2种常见停止方式
    java中的线程(1):如何正确停止线程Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
    android上最多有多少个http连接?
    采用MQTT协议实现android消息推送(4)选fusesource-mqtt-client为客户端
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6653405.html
Copyright © 2011-2022 走看看